在正式開始前澈驼,我們可以思考一個問題,學習一門技術難嗎筛武?不少人的答案可能是很難缝其。
來看一個案例,也可以說是兩個徘六。
2017年蘋果WWDC大會上内边,有兩名開發(fā)者令世界矚目。一個是已經(jīng)82歲待锈,來自日本的老太太漠其,若宮正子;另一個是年僅10歲竿音,來自澳大利亞的小朋友和屎,Yuma。前者60歲時才接觸電腦春瞬,81歲時用上Mac系統(tǒng)柴信,然后花了半年時間開發(fā)出了自己的app;后者從6歲開始設計網(wǎng)站宽气,隨后四年為蘋果商店貢獻了五個app颠印。有意思的是,兩個人都有自己的編程課堂抹竹,老太太在自己家教老人電腦知識,小Yuma建了一個Youtube頻道止潮,叫 Anyone Can Code(人人皆可編程)窃判,主要教小孩編程。
或許有人想說喇闸,他們不過是天賦好罷了袄琳。但我只想說,這種想法不過是不敢跳出舒適區(qū)燃乍,為自己的懶惰和無能找借口罷了唆樊。
如今,各種底層技術已經(jīng)經(jīng)過層層封裝刻蟹,可以說逗旁,只要你有想法,編程甚至能夠像搭積木一樣簡單。
首先片效,你有什么需求红伦,你的這個需求可以被什么技術解決,了解它的基本概念淀衣,然后把它變成生活的一部分昙读,想方設法用它。遇到問題了怎么辦膨桥?把大問題拆分成小問題蛮浑,找搜索引擎解答。
記住一點:你沒必要學習某技術的所有知識只嚣,了解基本概念沮稚,基本原理,就可以用它了介牙。
有人又會說了壮虫,我沒啥需求怎么辦?李敖曾說過:“作家不能等有了靈感才寫作环础,一如妓女不能等有了性欲才接客囚似。”
下面我們來學習shell腳本吧线得。主要面向linux初學者以及對linux感興趣的人饶唤。請自行準備linux系統(tǒng)或Mac系統(tǒng)。
什么是Linux內(nèi)核贯钩?
我們大多知道操作系統(tǒng)募狂,但少有人知道內(nèi)核,像CenOS角雷,Redhat祸穷,Ubuntu等,這是操作系統(tǒng)勺三,內(nèi)核是Linux kernel雷滚,它是操作系統(tǒng)的心臟,是操作系統(tǒng)的大腦吗坚,去掉它祈远,操作系統(tǒng)將不復存在,你的電腦也會成為破銅爛鐵商源。
不用過于深究车份,你可以簡單地將內(nèi)核看做電腦的大管家,它的小弟們與它一起構成了操作系統(tǒng)牡彻,共同管理計算機資源扫沼。
什么是shell?
我們知道,計算機實際只懂0和1(二進制)充甚,我們與外國人溝通需要靠翻譯以政,那么同計算機溝通當然也需要一個翻譯,shell就是這個翻譯伴找。另外盈蛮,你以為你是同計算機對話,其實不然技矮,你實際上是同內(nèi)核對話抖誉,你在電腦上看到的內(nèi)存啊,磁盤啊衰倦,CPU等都是虛擬出來的袒炉,你的任何操作,最終都是由內(nèi)核真正在計算機硬件上執(zhí)行樊零。
總結(jié)下shell定義:
- 一個命令語言解釋器我磁,你執(zhí)行的命令都由它翻譯給內(nèi)核,由內(nèi)核轉(zhuǎn)交給CPU執(zhí)行
- 是用戶與內(nèi)核之間的接口程序
- 不管是圖形界面(GUI)還是命令行界面(CLI)驻襟,用戶的一切輸入都先由shell解釋后再交給內(nèi)核
什么是bash shell夺艰?
shell的版本有很多像什么sh、bash沉衣、csh郁副、ksh等,其中bash是Linux世界使用最廣泛的shell豌习,也是很多Linux發(fā)行版的默認shell存谎。
獲取當前系統(tǒng)可用shell
[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
查看當前使用的shell
[root@localhost ~]# echo $SHELL
/bin/bash
什么是CLI和GUI?
- CLI:Command Line Interface(命令行接口)
- GUI:Graphical User Interface(圖形用戶接口)
- 顧名思義肥隆,CLI就是命令行界面既荚,GUI就是圖形界面
- 我們在電影看到的那些黑客的電腦界面,花花綠綠的栋艳,執(zhí)行一條命令就會有一大堆輸出的叫命令行界面固以,我們平時用的windows系統(tǒng),用鼠標在上面點點點的嘱巾,叫圖形界面,Linux當然也有自己的圖形界面
- 我們同shell對話诫钓,就是通過這兩種接口進行的
嘗試執(zhí)行幾個基本命令
[root@localhost ~]# echo "hello,linux"
hello,linux
[root@localhost ~]# date
Sat Jan 12 23:48:13 CST 2019
什么是標準輸入旬昭、標準輸出和標準錯誤輸出?
- 或許你曾聽說過:linux里面一切皆文件菌湃,所謂的標準輸入问拘、標準輸出和標準錯誤輸出其實都是文件
- 標準輸入,缺省是終端鍵盤,所謂缺省骤坐,即系統(tǒng)默認狀態(tài)
- 標準輸出绪杏,缺省是終端屏幕,至于終端這個概念纽绍,你就簡單理解為顯示器加鍵盤吧
- 標準錯誤輸出蕾久,缺省是終端屏幕
我們執(zhí)行一條shell命令,就會打開這三個文件拌夏,你可以理解為三條管道僧著,標準輸入與鍵盤相連,標準輸出和標準錯誤輸出都默認與屏幕相連障簿。沒有特別指明的情況下盹愚,我們通過鍵盤輸入的內(nèi)容通過“標準輸入”這條管道“流入”至相應的命令,命令的執(zhí)行結(jié)果又會通過“標準輸出”或“標準錯誤輸出”這條管道“流出”至屏幕站故,展現(xiàn)在我們面前皆怕。
比如輸入cat test.txt
,cat這個命令作用是從命令行給出的文本中讀取數(shù)據(jù)并將數(shù)據(jù)送到標準輸出西篓。
如果test.txt中有內(nèi)容愈腾,那么標準輸入就不是鍵盤了,而是該文件污淋,文件內(nèi)容通過“標準輸入”這個“管道”流向cat命令顶滩,cat命令讀取其內(nèi)容,然后將內(nèi)容“流出”至標準輸出寸爆,即屏幕上礁鲁。
# 將"hello"添加到test.txt這個文件中,如果不存在就創(chuàng)建
[root@localhost ~]# echo "hello" > test.txt
# 輸出test.txt文件內(nèi)容
[root@localhost ~]# cat test.txt
hello #標準輸出
假如test.txt
不存在赁豆,那么就會報錯仅醇,錯誤信息通過“標準錯誤輸出”這條管道“流出”至屏幕上。
[root@localhost ~]# cat test.txt
cat: test.txt: No such file or directory #標準錯誤輸出
假如cat
命令后面沒有參數(shù)魔种,那么其標準輸入便是鍵盤了析二,終端就會等待我們輸入,cat
獲取標準輸入节预,通過“標準輸出”這條管道輸出到屏幕上叶摄。
[root@localhost ~]# cat
hello # 標準輸入
hello # 標準輸出
什么是重定向?
比如一條命令cat test.txt
安拟,它會把test.txt
這個文件的內(nèi)容輸出到屏幕上蛤吓,但我不想輸出到屏幕上,我想保存到一個文件里糠赦,就可以用”標準輸出重定向“符號>
將其重定向到某個文件cat test.txt > temp.txt
会傲,這樣屏幕上就沒有輸出锅棕,也就改變了標準輸出的流出方向,故而稱之為”重定向“淌山。
-
>
又稱為”覆蓋重定向“裸燎,就是說會覆蓋輸出文件原先的內(nèi)容。 -
>>
被稱為”追加重定向“泼疑,也就是說不會覆蓋輸出文件的內(nèi)容德绿,而是把輸出追加到原內(nèi)容的后面 -
<
被稱為”標準輸入重定向“,一般命令的標準輸入都是鍵盤王浴,用了<
脆炎,其標準輸入就變成其后的文件了。比如氓辣,cat本身就能夠以文件作為其標準輸入秒裕,但我們也可以利用<
來將文件變成其標準輸入:cat < test.txt
- 前面又說了,所謂的
標準輸入
钞啸、標準輸出
以及標準錯誤輸出
其實都是文件几蜻,是文件就會有文件描述符,就像人的名字一樣体斩,不然內(nèi)核哪知道哪個文件是哪個文件啊梭稚。 -
標準輸入
的文件描述符是0
,標準輸出
是1
絮吵,標準錯誤輸出
是2弧烤。所以,如果我們想把cat test.txt
的標準輸出重定向到stdout.txt
蹬敲,其標準錯誤輸出重定向到stderr.txt
暇昂,可以這樣做:cat test.txt 1> stdout.txt 2> stderr.txt
,0
和1
一般都可以省略。 - 如何把
標準錯誤輸出
與標準輸出
重定向到同一個文件伴嗡?還是上面的例子:cat test.txt > temp.txt 2>&1
急波。還有一種方式是不區(qū)分標準錯誤輸出
與標準輸出
,統(tǒng)統(tǒng)重定向到同一個文件:cat test.txt &> temp.txt
什么是管道瘪校?
前面我們了解到澄暮,命令的標準輸出默認是屏幕,假如該命令的標準輸出我們想再利用怎么辦阱扬?那就需要利用管道了泣懊。強調(diào)一下,標準輸出是指命令執(zhí)行成功后的輸出麻惶。
舉個例子:
[root@localhost ~]# echo “zhangsan” | useradd
# 這條命令的意思是輸出”zhangsan“馍刮,并利用useradd命令添加其為linux普通用戶
# ”zhangsan“為管道前的標準輸出,管道將其變成后面useradd命令的標準輸入
注意事項:
- 管道只能處理前一個命令的標準輸出用踩,標準錯誤輸出無法處理
- 管道后面的命令必須能夠接受標準輸入才行渠退,像
ls
命令就不接受標準輸入,所以它不能放在管道后面脐彩。ls
命令的作用是列舉目錄下的內(nèi)容碎乃,當然了,在linux世界怎么能接受不能呢惠奸,利用xargs就可以把管道前的標準輸出當作ls
命令的標準輸入了
[root@localhost ~]# echo "/etc"| xargs ls
# 沒有xargs的話梅誓,這里的ls只能列舉當前目錄的內(nèi)容,而非/etc這個目錄
什么是shell腳本佛南?
前面說過梗掰,shell是一個命令語言解釋器。另外嗅回,shell本身也是一個程序及穗,有自己的命令,像什么ls绵载、cd埂陆、pwd等都是其內(nèi)置命令,還有一些其他命令娃豹,都是別人為linux添加的基本命令焚虱。我們知道,編程時通過各種庫調(diào)用來實現(xiàn)功能懂版,而shell沒有庫鹃栽,他通過調(diào)用各種命令來實現(xiàn)相應功能。
我們通過輸入各種命令與shell交互躯畴,但有時我們不想手動輸入各種命令民鼓,我們想把命令存在一個文件中,然后讓shell執(zhí)行該文件中的命令私股,于是就有了shell腳本摹察。
所謂的shell腳本其實就是一個包含一系列shell命令的文本,目的是減少重復工作倡鲸,實現(xiàn)自動化供嚎。
shell腳本基本組件
shell腳本是由各種shell命令組成,但絕對不是簡單的命令堆積峭状,它像其他編程語言一樣克滴,有自己的基本組件。
- shell命令
- shell內(nèi)部命令优床,如ls劝赔、cd、pwd等
- 其他命令
- who胆敞、du着帽、free等各種豐富的功能命令
- 數(shù)據(jù)結(jié)構
- 變量杂伟、數(shù)組、字典
- 函數(shù)
- 將一系列命令組合成一個函數(shù)仍翰,減少重復工作
- 控制流
- if赫粥、case等分支語句
- for、while等循環(huán)語句
如何快速編寫一個腳本予借?
腳本組成
一個完整的腳本有三部分組成:腳本聲明越平、注釋以及可執(zhí)行語句。
- 腳本聲明
- 前面說過灵迫,CPU只認識二進制秦叛,也就是說只能執(zhí)行二進制程序文件
- 我們的腳本是文本文件,需要一個解釋者解釋下瀑粥,也就是shell挣跋,shell本身是二進制程序
- CPU運行shell程序,shell解釋腳本的每一行內(nèi)容利凑,然后找到對應的二進制程序浆劲,由CPU執(zhí)行
- 所以,首先我們得告訴CPU哀澈,該腳本用哪個解釋器來解釋
- 如何聲明牌借,在腳本第一行頂格寫:#!/bin/bash
-
#!
被稱為shebang符號,用來聲明所使用的解釋器割按,一旦執(zhí)行某個腳本膨报,CPU看到第一行,就會去執(zhí)行該解釋器适荣,再由解釋器去找對應的命令程序 - /bin/bash指明bash二進制程序的位置
- 注釋
- 簡單的腳本還好现柠,一旦復雜起來,可讀性就大大降低弛矛,所以注釋相當重要
- 解釋器會忽略注釋
- shell腳本中的單行注釋符號是
#
- 至于多行注釋够吩,方法有很多,一般用不到的丈氓,想用的話周循,自己在網(wǎng)上搜搜
吧
- 可執(zhí)行語句
- linux命令以及相應的控制流與數(shù)據(jù)結(jié)構
- 相關語法可以在網(wǎng)上找
- 需要條件判斷了,就搜
shell if語法
或shell case語法
- 需要重復執(zhí)行某命令万俗,就搜
shell for循環(huán)
或shell while循環(huán)
- 某個需求不知道用什么命令湾笛,就搜
需求關鍵字
好了 - 某個命令不知道怎么用,直接在命令行輸入
man 命令
或者直接百度
一個批量ping ip腳本
說了這么多闰歪,讓我們開始寫一個腳本吧嚎研,先說一個命令,檢測網(wǎng)絡通不通库倘,需要用到ping命令临扮,我們想批量檢測某一個網(wǎng)段的主機是否網(wǎng)絡通暢论矾,那就需要用到for循環(huán)。
#linux中默認編輯器通常是vi或vim杆勇,該文本編輯器分為三種模式
#默認是普通模式(無法輸入內(nèi)容拇囊,但可以通過相應命令操作文本),普通模式下按i表示進入插入模式(可以插入內(nèi)容了)
#按:表示進入命令行模式(批量操作文本)靶橱,在插入模式或命令行模式下按ESC進入普通模式。輸入ZZ或:wq退出vim編輯器
[root@localhost ~]# vim ping.sh
#默認進入普通模式路捧,先按i開始編寫腳本关霸,下面是腳本完整內(nèi)容
#!/bin/bash
NET=192.168.1 #聲明一個變量并賦值
for i in {1..254} #后面的{1..254}表示循環(huán)范圍從1-254,如果你就是想測試下杰扫,這里就改成{1..10}吧
do
IP=$NET.$i #字符拼接并賦值給IP這個變量
ping -c 3 $IP &> /dev/null
#-c指明發(fā)包次數(shù)队寇,&> /dev/null表示無論正確輸出還是錯誤輸出統(tǒng)統(tǒng)丟棄
#$?表示上條命令的執(zhí)行結(jié)果,0表示成功章姓,非0表示失敗
#-eq代表”是否等于“佳遣,[]是條件測試語法,測試條件左右必須各留至少一個空格
if [ $? -eq 0 ];then
echo "$IP is up"
else
echo "$IP is down"
fi
done
# 編寫完畢凡伊,按ECS進入普通模式零渐,然后輸入:wq退出vim編輯器
腳本執(zhí)行
執(zhí)行腳本主要有三種方法:
- 直接運行腳本文件
- 這種方法需要腳本有可執(zhí)行權限:chmod u+x ping.sh
- 然后輸入腳本的絕對路徑或相對路徑來執(zhí)行文件
- 比如相對路徑,你得先進入腳本所在的目錄系忙,然后執(zhí)行:./ping.sh
- 利用解釋器執(zhí)行
- bash ping.sh
- sh ping.sh
- 利用source或.
- source ping.sh
- . ping.sh
第一種方法诵盼,如果你沒有shebang語句(即第一行聲明解釋器),可能會報錯银还;第二種方法风宁,你可以不聲明解釋器類型,因為你是直接用解釋器來執(zhí)行的蛹疯,也可以不賦予執(zhí)行權限戒财;第三種方法,你是在當前shell環(huán)境來執(zhí)行的捺弦,前兩種實際上都是在子shell中執(zhí)行饮寞,執(zhí)行完畢才退回到當前shell。
基本上用哪種方法都行羹呵,看你心情骂际。
# 假如你想把執(zhí)行結(jié)果保存到一個文件,也就會利用輸出重定向
# 但同時你又想輸出其結(jié)果到屏幕上冈欢,那就會用到tee命令了
[root@localhost ~]# bash ping.sh | tee out.txt
192.168.1.1 is up
192.168.1.2 is down
...
#現(xiàn)在你想知道有多少個ip是通的歉铝,這就用到涉及文本過濾命令grep以及統(tǒng)計命令wc
[root@localhost ~]# grep "up" out.txt | wc -l
3
最后補充一點,同window不同凑耻,linux世界太示,文件后綴沒有任何意義柠贤,加后綴名只是方便人類自己查看。
學習一門新技術类缤,最痛苦的過程只是前兩小時臼勉,熬過了這兩小時,后面就會越走越順餐弱。