日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux-basic(13)学习shell script

發(fā)布時間:2023/12/3 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux-basic(13)学习shell script 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
【13.1】什么是shell script?
1)shell script 是利用 shell 的功能所寫的一個『程序 (program)』,這個程序是使用純文字檔,將一些 shell 的語法與命令(含外部命令)寫在里面, 搭配正規(guī)表示法、管線命令與數(shù)據(jù)流重導(dǎo)向等功能,以達(dá)到我們所想要的處理目的。
  • 1.1)簡單的說, shell script 就像是早期 DOS 年代的批量檔 (.bat) ,最簡單的功能就是將許多命令匯整寫在一起, 讓使用者很輕易的就能夠 one touch 的方法去處理復(fù)雜的動作 (運(yùn)行一個文件 "shell script" ,就能夠一次運(yùn)行多個命令)。 而且 shell script 更提供陣列、回圈、條件與邏輯判斷等重要功能,讓使用者也可以直接以 shell 來撰寫程序,而不必使用類似 C 程序語言等傳統(tǒng)程序撰寫的語法呢!?
  • 1.2)shell script 可以簡單的被看成是批量檔, 也可以被說成是一個程序語言,且這個程序語言由於都是利用 shell 與相關(guān)工具命令, 所以不需要編譯即可運(yùn)行,且擁有不錯的除錯 (debug) 工具,所以,他可以幫助系統(tǒng)管理員快速的管理好主機(jī)。
2)shell script 用在系統(tǒng)管理上面是很好的一項(xiàng)工具,但是用在處理大量數(shù)值運(yùn)算上, 就不夠好了,因?yàn)?Shell scripts 的速度較慢,且使用的 CPU 資源較多,造成主機(jī)資源的分配不良。還好, 我們通常利用 shell script 來處理服務(wù)器的偵測,倒是沒有進(jìn)行大量運(yùn)算的需求啊!所以不必?fù)?dān)心的啦!

【13.1.2】第一個 script 的編寫與執(zhí)行
1)shell編寫規(guī)則:在 shell script 的撰寫中還需要用到底下的注意事項(xiàng):
  • ? 1. 命令的運(yùn)行是從上而下、從左而右的分析與運(yùn)行;
  • ? 2. 命令的下達(dá)就如同第五章內(nèi)提到的: 命令、選項(xiàng)與參數(shù)間的多個空白都會被忽略掉;
  • ? 3. 空白行也將被忽略掉,并且 [tab] 按鍵所推開的空白同樣視為空白鍵;
  • ? 4. 如果讀取到一個 Enter 符號 (CR) ,就嘗試開始運(yùn)行該行 (或該串) 命令;
  • ? 5. 至於如果一行的內(nèi)容太多,則可以使用『 \[Enter] 』來延伸至下一行;
  • ? 6. 『 # 』可做為注解!任何加在 # 后面的數(shù)據(jù)將全部被視為注解文字而被忽略!
2)shell執(zhí)行方式:假設(shè)你寫的這個程序檔名是 /home/dmtsai/shell.sh 好了,那如何運(yùn)行這個文件?很簡單,可以有底下幾個方法:
? ● 直接命令下達(dá): shell.sh 文件必須要具備可讀與可運(yùn)行 (rx) 的權(quán)限,然后:
? ? ? ○ 絕對路徑:使用 /home/dmtsai/shell.sh 來下達(dá)命令;
? ? ? ○ 相對路徑:假設(shè)工作目錄在 /home/dmtsai/ ,則使用 ./shell.sh 來運(yùn)行
? ? ? ○ 變量『PATH』功能:將 shell.sh 放在 PATH 指定的目錄內(nèi),例如: ~/bin/

? ● 以 bash 程序來運(yùn)行:透過『 bash shell.sh 』或『 sh shell.sh 』來運(yùn)行
補(bǔ)充:那為何『 sh shell.sh 』也可以運(yùn)行呢?這是因?yàn)?/bin/sh 其實(shí)就是 /bin/bash (連結(jié)檔),使用 sh shell.sh 亦即告訴系統(tǒng),我想要直接以 bash 的功能來運(yùn)行 shell.sh 這個文件內(nèi)的相關(guān)命令的意思,所以此時你的 shell.sh 只要有 r 的權(quán)限即可被運(yùn)行喔!

3)編寫第1個shell script
#!/bin/bash # Program: # This program shows "Hello World!" in your screen. # History: # 2005/08/23 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH echo -e "Hello World! \a \n" exit 0 (1)
【13.1.3】編寫shell script的良好習(xí)慣
1)建議你一定要養(yǎng)成良好的 script 撰寫習(xí)慣,在每個 script 的檔頭處記錄好:
? ● script 的功能;
? ● script 的版本資訊;
? ● script 的作者與聯(lián)絡(luò)方式;
? ● script 的版權(quán)宣告方式;
? ● script 的 History (歷史紀(jì)錄);
? ● script 內(nèi)較特殊的命令,使用『絕對路徑』的方式來下達(dá);
? ● script 運(yùn)行時需要的環(huán)境變量預(yù)先聲明與設(shè)置。

【13.2】簡單的shell script練習(xí)
【13.2.1】簡單范例

1)交互式腳本:變量內(nèi)容由用戶決定
請你以 read 命令的用途,撰寫一個 script ,他可以讓使用者輸入:1. first name 與 2. last name, 最后并且在螢?zāi)簧巷@示:『Your full name is: 』的內(nèi)容:
(2)
#!/bin/bash # Program: # User inputs his first name and last name. Program shows his full name. # History: # 2005/08/23 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATHread -p "Please input your first name: " firstname # 提示使用者輸入 read -p "Please input your last name: " lastname # 提示使用者輸入 echo -e "\nYour full name is: $firstname $lastname" # 結(jié)果由螢?zāi)惠敵?
2)隨日期變化:利用日期進(jìn)行文件的創(chuàng)建:
假設(shè)我想要創(chuàng)建三個空文件(透過touch) ,檔名最開頭由使用者輸入決定,假設(shè)使用者輸入 filename 好了,那今天的日期是 2009/02/14 , 我想要以前天、昨天、今天的日期來創(chuàng)建這些文件,亦即 filename_20090212, filename_20090213, filename_20090214 ,該如何是好?
[root@localhost scripts]# vim sh03.sh #!/bin/bash # Program: # Program creates three files, which named by user's input # and date command. # History: # 2018/05/01 tang rong First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH# 1. 讓使用者輸入文件名稱,并取得 fileuser 這個變量; echo -e "I will use 'touch' command to create 3 files." # 純粹顯示資訊 read -p "Please input your filename: " fileuser # 提示使用者輸入# 2. 為了避免使用者隨意按 Enter ,利用變量功能分析檔名是否有配置? filename=${fileuser:-"filename"} # 開始判斷有否配置檔名# 3. 開始利用 date 命令來取得所需要的檔名了; date1=$(date --date='2 days ago' +%Y%m%d) # 前兩天的日期 date2=$(date --date='1 days ago' +%Y%m%d) # 前一天的日期 date3=$(date +%Y%m%d) # 今天的日期 file1=${filename}${date1} # 底下三行在配置檔名 file2=${filename}${date2} file3=${filename}${date3}# 4. 將檔名創(chuàng)建吧! touch "$file1" # 底下三行在創(chuàng)建文件 touch "$file2" touch "$file3"
(3)


(4)
3)數(shù)值運(yùn)算:簡單的加減乘除
如果我們要使用者輸入兩個變量, 然后將兩個變量的內(nèi)容相乘,最后輸出相乘的結(jié)果,那可以怎么做?

(5)
補(bǔ)充:鳥哥比較建議使用這樣的方式來進(jìn)行運(yùn)算:
var=$((運(yùn)算內(nèi)容))
不但容易記憶,而且也比較方便的多,因?yàn)閮蓚€小括號內(nèi)可以加上空白字節(jié)喔! 未來你可以使用這種方式來計算的呀!至於數(shù)值運(yùn)算上的處理,則有:『 +, -, *, /, % 』等等。 那個 % 是取余數(shù)啦~舉例來說, 13 對 3 取余數(shù),結(jié)果是 13=4*3+1,所以余數(shù)是 1 啊!就是:

(6)
【13.2.2】script的執(zhí)行方式差別(source, sh script, ./script)
1)腳本的運(yùn)行方式除了前面小節(jié)談到的方式之外,還可以利用 source 或小數(shù)點(diǎn) (.) 來運(yùn)行喔!那么這種運(yùn)行方式有何不同呢?
方式1)利用直接執(zhí)行的方式來執(zhí)行script
當(dāng)使用前一小節(jié)提到的直接命令下達(dá) (不論是絕對路徑/相對路徑還是 $PATH 內(nèi)),或者是利用 bash (或 sh) 來下達(dá)腳本時, 該 script 都會使用一個新的 bash 環(huán)境來運(yùn)行腳本內(nèi)的命令!也就是說,使用這種運(yùn)行方式時, 其實(shí) script 是在子程序的 bash 內(nèi)運(yùn)行的!
重點(diǎn)在于:『當(dāng)子程序完成后,在子程序內(nèi)的各項(xiàng)變量或動作將會結(jié)束而不會傳回到父程序中』!

【荔枝】我們舉剛剛提到過的 sh02.sh 這個腳本來說明好了,這個腳本可以讓使用者自行配置兩個變量,分別是 firstname 與 lastname,想一想,如果你直接運(yùn)行該命令時,該命令幫你配置的 firstname 會不會生效?

(7)
1.2)利用source來執(zhí)行腳本:在父進(jìn)程中執(zhí)行

(8)

【13.3】善用判斷式

【13.3.1】利用test命令的測試功能
1)判斷 /trong 這個目錄存在與否
(9)
2)那我知道 -e 是測試一個『東西』在不在, 如果還想要測試一下該檔名是啥玩意兒時,還有哪些標(biāo)志可以來判斷的呢?呵呵!有底下這些東西喔!
(10)
(11)
3)OK!現(xiàn)在我們就利用 test 來幫我們寫幾個簡單的例子。首先,判斷一下,讓使用者輸入一個檔名,我們判斷:?
  • 判斷1)這個文件是否存在,若不存在則給予一個『Filename does not exist』的信息,并中斷程序;
  • 判斷2)若這個文件存在,則判斷他是個文件或目錄,結(jié)果輸出『Filename is regular file』或 『Filename is directory』;
  • 判斷3)判斷一下,運(yùn)行者的身份對這個文件或目錄所擁有的權(quán)限,并輸出權(quán)限數(shù)據(jù)!
(12)
(13)
#!/bin/bash # Program: # User input a filename, program will check the flowing: # 1.) exist? 2.) file/directory? 3.) file permissions # History: # 2005/08/25 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH# 1. 讓使用者輸入檔名,并且判斷使用者是否真的有輸入字串? echo -e "Please input a filename, I will check the filename's type and \ permission. \n\n" read -p "Input a filename : " filename test -z $filename && echo "You MUST input a filename." && exit 0 # 2. 判斷文件是否存在?若不存在則顯示信息并結(jié)束腳本 test ! -e $filename && echo "The filename '$filename' DO NOT exist" && exit 0 # 3. 開始判斷文件類型與屬性 test -f $filename && filetype="regulare file" test -d $filename && filetype="directory" test -r $filename && perm="readable" test -w $filename && perm="$perm writable" test -x $filename && perm="$perm executable" # 4. 開始輸出資訊! echo "The filename: $filename is a $filetype" echo "And the permissions are : $perm"

【13.3.2】利用判斷符號[]
1)除了我們很喜歡使用的 test 之外,其實(shí),我們還可以利用判斷符號『 [ ] 』(就是中括號啦) 來進(jìn)行數(shù)據(jù)的判斷呢! 舉例來說,如果我想要知道 $HOME 這個變量是否為空的,可以這樣做:


(14)
補(bǔ)充1:如果要在 bash 的語法當(dāng)中使用中括號作為 shell 的判斷式時,必須要注意中括號的兩端需要有空白字節(jié)來分隔喔!
補(bǔ)充2)假設(shè)我空白鍵使用『□』符號來表示,那么,在這些地方你都需要有空白鍵:
(15)
所以說,你最好要注意:
? ● 在中括號 [] 內(nèi)的每個組件都需要有空白鍵來分隔;
? ● 在中括號內(nèi)的變量,最好都以雙引號括號起來;
? ● 在中括號內(nèi)的常數(shù),最好都以單或雙引號括號起來。
【荔枝】利用中括號[] 進(jìn)行判斷,加引號的區(qū)別
(16)
【荔枝】那我們也使用中括號的判斷來做一個小案例好了,案例配置如下:
? 1. 當(dāng)運(yùn)行一個程序的時候,這個程序會讓使用者選擇 Y 或 N ,
? 2. 如果使用者輸入 Y 或 y 時,就顯示『 OK, continue 』
? 3. 如果使用者輸入 n 或 N 時,就顯示『 Oh, interrupt !』
? 4. 如果不是 Y/y/N/n 之內(nèi)的其他字節(jié),就顯示『 I don't know what your choice is 』
利用中括號[]、 && 與 || 來繼續(xù)吧!


(17)
【13.3.3】shell script的默認(rèn)變量($0、 $1 ......)
1)如果你想要重新啟動系統(tǒng)登錄檔的功能,可以這樣做:


(18)
2)script 是怎么達(dá)成這個功能的呢?其實(shí) script 針對參數(shù)已經(jīng)有配置好一些變量名稱了!對應(yīng)如下:


(19)
3)除了這些數(shù)字的變量之外, 我們還有一些較為特殊的變量可以在 script 內(nèi)使用來調(diào)用這些參數(shù)喔!
? ● $# :代表后接的參數(shù)『個數(shù)』,以上表為例這里顯示為『 4 』;
? ● $@ :代表『 "$1" "$2" "$3" "$4" 』之意,每個變量是獨(dú)立的(用雙引號括起來);
? ● $* :代表『 "$1c$2c$3c$4" 』,其中 c 為分隔字節(jié),默認(rèn)為空白鍵, 所以本例中代表『 "$1 $2 $3 $4" 』之意。


【荔枝】假設(shè)我要運(yùn)行一個可以攜帶參數(shù)的 script ,運(yùn)行該腳本后螢?zāi)粫@示如下的數(shù)據(jù):
  • ? ● 程序的檔名為何?
  • ? ● 共有幾個參數(shù)?
  • ? ● 若參數(shù)的個數(shù)小於 2 則告知使用者參數(shù)數(shù)量太少
  • ? ● 全部的參數(shù)內(nèi)容為何?
  • ? ● 第一個參數(shù)為何?
  • ? ● 第二個參數(shù)為何。

(20)
3)shift:造成參數(shù)變量號碼偏移
【荔枝】那個 shift 會移動變量,而且 shift 后面可以接數(shù)字,代表拿掉最前面的幾個參數(shù)的意思。


(21)
【13.4】條件判斷式
【13.4.1】利用 if...then

1)單層、簡單條件判斷式: 如果你只有一個判斷式要進(jìn)行,那么我們可以簡單的這樣看:


(22)
1.1)如果我有多個條件要判別時,我還可以有多個中括號來隔開喔!而括號與括號之間,則以 && 或 || 來隔開,他們的意義是:
? ● && 代表 AND ;
? ● || 代表 or ;
1.2)所以,在使用中括號的判斷式中, && 及 || 就與命令下達(dá)的狀態(tài)不同了。舉例來說, sh06.sh 里面的判斷式可以這樣修改:
[ "$yn" == "Y" -o "$yn" == "y" ]
上式可替換為
[ "$yn" == "Y" ] || [ "$yn" == "y" ]
之所以這樣改,很多人是習(xí)慣問題!很多人則是喜歡一個中括號僅有一個判別式的原因。


【荔枝】將sh06.sh 修改為 if...then 的樣式看看:


(23)
2)多重、復(fù)雜條件判斷式
2.1)一個條件判斷


(24)
2.2)多個條件判斷


(25)
注意:你得要注意的是, elif 也是個判斷式,因此出現(xiàn) elif 后面都要接 then 來處理!但是 else 已經(jīng)是最后的沒有成立的結(jié)果了, 所以 else 后面并沒有 then 喔!好!我們來將 sh06-2.sh 改寫成這樣:
【荔枝】將 多個if 語句改為 elif 語句


(26)
3)一般來說,如果你不希望使用者由鍵盤輸入額外的數(shù)據(jù)時, 可以使用上一節(jié)提到的參數(shù)功能 ($1)!讓使用者在下達(dá)命令時就將參數(shù)帶進(jìn)去! 現(xiàn)在我們想讓使用者輸入『 hello 』這個關(guān)鍵字時,利用參數(shù)的方法可以這樣依序設(shè)計:
? 1. 判斷 $1 是否為 hello,如果是的話,就顯示 "Hello, how are you ?";
? 2. 如果沒有加任何參數(shù),就提示使用者必須要使用的參數(shù)下達(dá)法;
? 3. 而如果加入的參數(shù)不是 hello ,就提醒使用者僅能使用 hello 為參數(shù)。
整個程序的撰寫可以是這樣的:


(27)
【荔枝】 netstat命令:查詢到目前主機(jī)打開的網(wǎng)絡(luò)服務(wù)端口
荔枝1)我可以利用『 netstat -tuln 』來取得目前主機(jī)有啟動的服務(wù):
(28)
補(bǔ)充:上面的重點(diǎn)是『Local Address (本地主機(jī)的IP與端口對應(yīng))』那個欄位,他代表的是本機(jī)所啟動的網(wǎng)絡(luò)服務(wù)! IP的部分說明的是該服務(wù)位於那個介面上,若為 127.0.0.1 則是僅針對本機(jī)開放,若是 0.0.0.0 或 ::: 則代表對整個 Internet 開放。 每個端口 (port) 都有其特定的網(wǎng)絡(luò)服務(wù),幾個常見的 port 與相關(guān)網(wǎng)絡(luò)服務(wù)的關(guān)系是:
? ● 80: WWW
? ● 22: ssh
? ● 21: ftp
? ● 25: mail
? ● 111: RPC(遠(yuǎn)程程序呼叫)
? ● 631: CUPS(列印服務(wù)功能)


荔枝2)假設(shè)我的主機(jī)有興趣要偵測的是比較常見的 port 21, 22, 25及 80 時,那我如何透過 netstat 去偵測我的主機(jī)是否有開啟這四個主要的網(wǎng)絡(luò)服務(wù)端口呢?由於每個服務(wù)的關(guān)鍵字都是接在冒號『 : 』后面, 所以可以藉由擷取類似『 :80 』來偵測的!那我就可以簡單的這樣去寫這個程序喔:


(29)
【荔枝】寫個腳本程序來跑,讓使用者輸入他的退伍日期,讓你去幫他計算還有幾天才退伍?
由於日期是要用相減的方式來處置,所以我們可以透過使用 date 顯示日期與時間,將他轉(zhuǎn)為由 1970-01-01 累積而來的秒數(shù), 透過秒數(shù)相減來取得剩余的秒數(shù)后,再換算為日數(shù)即可。整個腳本的制作流程有點(diǎn)像這樣:
? 1. 先讓使用者輸入他們的退伍日期;
? 2. 再由現(xiàn)在日期比對退伍日期;
? 3. 由兩個日期的比較來顯示『還需要幾天』才能夠退伍的字樣。
似乎挺難的樣子?其實(shí)也不會啦,利用『 date --date="YYYYMMDD" +%s 』轉(zhuǎn)成秒數(shù)后,接下來的動作就容易的多了!


(30)
#!/bin/bash # Program: # You input your demobilization date, I calculate how many days # before you demobilize. # History: # 2005/08/29 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH# 1. 告知使用者這支程序的用途,并且告知應(yīng)該如何輸入日期格式? echo "This program will try to calculate :" echo "How many days before your demobilization date..." read -p "Please input your demobilization date (YYYYMMDD ex>20090401): " date2# 2. 測試一下,這個輸入的內(nèi)容是否正確?利用正規(guī)表示法羅~ date_d=$(echo $date2 |grep '[0-9]\{8\}') # 看看是否有八個數(shù)字 if [ "$date_d" == "" ]; thenecho "You input the wrong date format...."exit 1 fi# 3. 開始計算日期羅~ declare -i date_dem=`date --date="$date2" +%s` # 退伍日期秒數(shù) declare -i date_now=`date +%s` # 現(xiàn)在日期秒數(shù) declare -i date_total_s=$(($date_dem-$date_now)) # 剩余秒數(shù)統(tǒng)計 declare -i date_d=$(($date_total_s/60/60/24)) # 轉(zhuǎn)為日數(shù) if [ "$date_total_s" -lt "0" ]; then # 判斷是否已退伍echo "You had been demobilization before: " $((-1*$date_d)) " ago" elsedeclare -i date_h=$(($(($date_total_s-$date_d*60*60*24))/60/60))echo "You will demobilize after $date_d days and $date_h hours." fi

(31)
【13.4.2】利用 case...esac 判斷
(32)
【荔枝】把 sh09.sh 修改一下,如下:

(33)
#!/bin/bash # Program: # Show "Hello" from $1.... by using case .... esac # History: # 2005/08/29 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATHcase $1 in"hello")echo "Hello, how are you ?";;"")echo "You MUST input parameters, ex> {$0 someword}";;*) # 其實(shí)就相當(dāng)於萬用字節(jié),0~無窮多個任意字節(jié)之意!echo "Usage $0 {hello}";; esac
(34)
【補(bǔ)充】一般來說,使用『 case $變量 in 』這個語法中,當(dāng)中的那個『 $變量 』大致有兩種取得的方式:
? ● 直接下達(dá)式:例如上面提到的,利用『 script.sh variable 』 的方式來直接給予 $1 這個變量的內(nèi)容,這也是在 /etc/init.d 目錄下大多數(shù)程序的設(shè)計方式。
? ● 互動式:透過 read 這個命令來讓使用者輸入變量的內(nèi)容。

【荔枝】讓使用者能夠輸入 one, two, three , 并且將使用者的變量顯示到屏幕上,如果不是 one, two, three 時,就告知使用者僅有這三種選擇。(通過直接執(zhí)行式來傳入?yún)?shù),即利用 script.sh variable 的方式來直接給予 $1 這個變量的內(nèi)容)

(35)?
#!/bin/bash # Program: # This script only accepts the flowing parameter: one, two or three. # History: # 2005/08/29 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATHecho "This program will print your selection !" # read -p "Input your choice: " choice # 暫時取消,可以替換! # case $choice in # 暫時取消,可以替換! case $1 in # 現(xiàn)在使用,可以用上面兩行替換!"one")echo "Your choice is ONE";;"two")echo "Your choice is TWO";;"three")echo "Your choice is THREE";;*)echo "Usage $0 {one|two|three}";; esac 【繼續(xù)荔枝】讓使用者能夠輸入 one, two, three , 并且將使用者的變量顯示到屏幕上,如果不是 one, two, three 時,就告知使用者僅有這三種選擇。(通過read命令讀入用戶輸入的變量內(nèi)容)

(36)
【13.4.3】利用function功能
1)function的語法如下:
function fname() {
程序段
}
那個 fname 就是我們的自訂的運(yùn)行命令名稱~而程序段就是我們要他運(yùn)行的內(nèi)容了。 要注意的是,因?yàn)?shell script 的運(yùn)行方式是由上而下,由左而右, 因此在 shell script 當(dāng)中的 function 的配置一定要在程序的最前面, 這樣才能夠在運(yùn)行時被找到可用的程序段喔!

【荔枝】定義一個名為 printit的函數(shù), 如下:

(37)
#!/bin/bash # Program: # Use function to repeat information. # History: # 2005/08/29 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATHfunction printit(){echo -n "Your choice is " # 加上 -n 可以不斷行繼續(xù)在同一行顯示 }echo "This program will print your selection !" case $1 in"one")printit; echo $1 | tr 'a-z' 'A-Z' # 將參數(shù)做大小寫轉(zhuǎn)換!;;"two")printit; echo $1 | tr 'a-z' 'A-Z';;"three")printit; echo $1 | tr 'a-z' 'A-Z';;*)echo "Usage $0 {one|two|three}";; esac2)另外, function 也是擁有內(nèi)建變量的~他的內(nèi)建變量與 shell script 很類似, 函數(shù)名稱代表示 $0 ,而后續(xù)接的變量也是以 $1, $2... 來取代的~ 這里很容易搞錯喔~因?yàn)椤?function fname() { 程序段 } 』內(nèi)的 $0, $1... 等等與 shell script 的 $0 是不同的。以上面 sh12-2.sh 來說,假如我下達(dá):『 sh sh12-2.sh one 』 這表示在 shell script 內(nèi)的 $1 為 "one" 這個字串。但是在 printit() 內(nèi)的 $1 則與這個 one 無關(guān)。?

【荔枝】將上面的例子再次改寫一下,如下:
(38)
[root@localhost scripts]# vim sh12-4.sh#!/bin/bash # Program: # Use function to repeat information. # History: # 2005/08/29 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATHfunction printit(){echo "Your choice is $1" # 這個 $1 必須要參考底下命令的下達(dá) }echo "This program will print your selection !" case $1 in"one")printit 1 # 請注意, printit 命令后面還有接參數(shù)!;;"two")printit 2;;"three")printit 3;;*)echo "Usage $0 {one|two|three}";; esac 【13.5】循環(huán)
【13.5.1】while do done, until do done (不定循環(huán))

1)循環(huán)方式
方式1) while do done 循環(huán):while 的中文是當(dāng)....時,所以,這種方式說的是『當(dāng) condition 條件成立時,就進(jìn)行循環(huán),直到 condition 的條件不成立才停止』的意思。
(39)
方式2)until do done 循環(huán)(不定循環(huán)):它說的是當(dāng) condition 條件成立時,就終止循環(huán), 否則就持續(xù)進(jìn)行循環(huán)的程序段。
(40)
【荔枝】while循環(huán):假設(shè)我要讓使用者輸入 yes 或者是 YES 才結(jié)束程序的運(yùn)行,否則就一直進(jìn)行告知使用者輸入字串。

(41)
(42)
【荔枝】想要計算 1+2+3+....+100 這個數(shù)據(jù)呢? 利用循環(huán)啊。
(43)
【13.5.2】for...do...done(固定循環(huán))
1)相對于 while, until 的循環(huán)方式是必須要『符合某個條件』的狀態(tài), for 這種語法,則是已經(jīng)知道要進(jìn)行幾次循環(huán)的狀態(tài)!他的語法是:

(44)
2)讓我們想像另外一種狀況,由於系統(tǒng)上面的各種帳號都是寫在 /etc/passwd 內(nèi)的第一個欄位,你能不能透過管線命令的 cut 捉出單純的帳號名稱后,以 id 及 finger 分別檢查使用者的識別碼與特殊參數(shù)呢?
(45)
【補(bǔ)充】
補(bǔ)充1)id命令: id 命令可以顯示真實(shí)有效的用戶 ID(UID) 和組 ID(GID)。UID 是對一個用戶的單一身份標(biāo)識。組 ID(GID)則對應(yīng)多個UID。
補(bǔ)充2)finger命令:finger命令用于查找并顯示用戶信息。包括本地與遠(yuǎn)端主機(jī)的用戶皆可,帳號名稱沒有大小寫的差別。單獨(dú)執(zhí)行finger指令,它會顯示本地主機(jī)現(xiàn)在所有的用戶的登陸信息,包括帳號名稱,真實(shí)姓名,登入終端機(jī),閑置時間,登入時間以及地址和電話。
(46)
【荔枝】利用 ping 這個可以判斷網(wǎng)絡(luò)狀態(tài)的命令, 來進(jìn)行網(wǎng)絡(luò)狀態(tài)的實(shí)際偵測時,我想要偵測的網(wǎng)域是本機(jī)所在的 192.168.1.1~192.168.1.100,由於有 100 臺主機(jī), 總不會要我在 for 后面輸入 1 到 100 吧?此時你可以這樣做喔!(但本機(jī)實(shí)驗(yàn)只取10臺機(jī)器!!)
(47)
#!/bin/bash # Program # Use ping command to check the network's PC state. # History # 2009/02/18 VBird first release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH network="192.168.1" # 先定義一個網(wǎng)域的前面部分! for sitenu in $(seq 1 10) # seq 為 sequence(連續(xù)) 的縮寫之意 do# 底下的程序在取得 ping 的回傳值是正確的還是失敗的!ping -c 1 -w 1 ${network}.${sitenu} &> /dev/null && result=0 || result=1# 開始顯示結(jié)果是正確的啟動 (UP) 還是錯誤的沒有連通 (DOWN)if [ "$result" == 0 ]; thenecho "Server ${network}.${sitenu} is UP."elseecho "Server ${network}.${sitenu} is DOWN."fi done 【荔枝】編寫判別式加上循環(huán)的功能: 我想要讓使用者輸入某個目錄文件名, 然后找出某目錄內(nèi)的文件名權(quán)限,該如何是好?
(48)


(49)
【13.5.3】for...do...done 的數(shù)值處理
1)for 循環(huán)還有另外一種寫法!語法如下:

(50)
2)這種語法適合於數(shù)值方式的運(yùn)算當(dāng)中,在 for 后面的括號內(nèi)的三串內(nèi)容意義為:
? ● 初始值:某個變量在回圈當(dāng)中的起始值,直接以類似 i=1 配置好;
? ● 限制值:當(dāng)變量的值在這個限制值的范圍內(nèi),就繼續(xù)進(jìn)行回圈。例如 i<=100;
? ● 運(yùn)行步階:每作一次回圈時,變量的變化量。例如 i=i+1。?


【荔枝】執(zhí)行從1的累加,上限是輸入的數(shù)字,如下:
(51)
【13.6】shell script的追蹤與調(diào)試
1)scripts 在運(yùn)行之前,最怕的就是出現(xiàn)語法錯誤的問題了!那么我們?nèi)绾?debug 呢? 有沒有辦法不需要透過直接運(yùn)行該 scripts 就可以來判斷是否有問題呢?呵呵!當(dāng)然是有的!我們就直接以 bash 的相關(guān)參數(shù)來進(jìn)行判斷吧!
(52)
【荔枝】
(53)

(54)
  • 補(bǔ)充1) 在輸出的信息中,在加號后面的數(shù)據(jù)其實(shí)都是命令串,由於 sh -x 的方式來將命令運(yùn)行過程也顯示出來, 如此使用者可以判斷程序碼運(yùn)行到哪一段時會出現(xiàn)相關(guān)的資訊!這個功能非常的棒!
  • 補(bǔ)充2)Linux 系統(tǒng)本來就有很多的服務(wù)啟動腳本,如果你想要知道每個 script 所代表的功能是什么? 可以直接以 vim 進(jìn)入該 script 去查閱一下,通常立刻就知道該 script 的目的了。 舉例來說,我們之前一直提到的 /etc/init.d/syslog ,這個 script 是干嘛用的? 利用 vi 去查閱最前面的幾行字,就知道這個 shell 腳本是干什么的了。
【13.8】本章習(xí)題
  • ? shell script 是利用 shell 的功能所寫的一個『程序 (program)』,這個程序是使用純文字檔,將一些 shell 的語法與命令(含外部命令)寫在里面, 搭配正規(guī)表示法、管線命令與數(shù)據(jù)流重導(dǎo)向等功能,以達(dá)到我們所想要的處理目的;
  • ? shell script 用在系統(tǒng)管理上面是很好的一項(xiàng)工具,但是用在處理大量數(shù)值運(yùn)算上, 就不夠好了,因?yàn)?Shell scripts 的速度較慢,且使用的 CPU 資源較多,造成主機(jī)資源的分配不良;
  • ? 在 Shell script 的文件中,命令的運(yùn)行是從上而下、從左而右的分析與運(yùn)行;
  • ? shell script 的運(yùn)行,至少需要有 r 的權(quán)限,若需要直接命令下達(dá),則需要擁有 r 與 x 的權(quán)限;
  • ? 良好的程序撰寫習(xí)慣中,第一行要宣告 shell (#!/bin/bash) ,第二行以后則宣告程序用途、版本、作者等;
  • ? 對談式腳本可用 read 命令達(dá)成;
  • ? 要創(chuàng)建每次運(yùn)行腳本都有不同結(jié)果的數(shù)據(jù),可使用 date 命令利用日期達(dá)成;
  • ? script 的運(yùn)行若以 source 來運(yùn)行時,代表在父程序的 bash 內(nèi)運(yùn)行之意!
  • ? 若需要進(jìn)行判斷式,可使用 test 或中括號 ( [] ) 來處理;
  • ? 在 script 內(nèi),$0, $1, $2..., $@ 是有特殊意義的!
  • ? 條件判斷式可使用 if...then 來判斷,若是固定變量內(nèi)容的情況下,可使用 case $var in ... esac 來處理;
  • ? 回圈主要分為不定回圈 (while, until) 以及固定回圈 (for) ,配合 do, done 來達(dá)成所需任務(wù)!
  • ? 我們可使用 sh -x script.sh 來進(jìn)行程序的 debug;





總結(jié)

以上是生活随笔為你收集整理的linux-basic(13)学习shell script的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。