一.什么是shell script
shell script 是利用 shell 的功能所寫的一個『程式 (program)』,這個程式是使用純文字檔,將一些 shell 的語法與指令(含外部指令)寫在裡面, 搭配正規表示法、管線命令與資料流重導向等功能,以達到我們所想要的處理目的。簡單的說, shell script 就像是早期 DOS 年代的批次檔 (.bat) ,最簡單的功能就是將許多指令彙整寫在一起, 讓使用者很輕易的就能夠 one touch 的方法去處理複雜的動作 (執行一個檔案 "shell script" ,就能夠一次執行多個指令)。
二.shell script的注意事项
①注意事项
- 指令的執行是從上而下、從左而右的分析與執行;
- 指令的下達就如同第四章內提到的: 指令、選項與參數間的多個空白都會被忽略掉;
- 空白行也將被忽略掉,並且 [tab] 按鍵所推開的空白同樣視為空白鍵;
- 如果讀取到一個 Enter 符號 (CR) ,就嘗試開始執行該行 (或該串) 命令;
- 至於如果一行的內容太多,則可以使用『 \[Enter] 』來延伸至下一行;
- 『 # 』可做為註解!任何加在 # 後面的資料將全部被視為註解文字而被忽略!
現在我們假設你寫的這個程式檔名是 /home/dmtsai/shell.sh 好了,那如何執行這個檔案?很簡單,可以有底下幾個方法:
- 直接指令下達: shell.sh 檔案必須要具備可讀與可執行 (rx) 的權限,然後:
- 絕對路徑:使用 /home/dmtsai/shell.sh 來下達指令;
- 相對路徑:假設工作目錄在 /home/dmtsai/ ,則使用 ./shell.sh 來執行
- 變數『PATH』功能:將 shell.sh 放在 PATH 指定的目錄內,例如: ~/bin/
- 以 bash 程式來執行:透過『 bash shell.sh 』或『 sh shell.sh 』來執行
②编写习惯
- script 的功能;
- script 的版本資訊;
- script 的作者與聯絡方式;
- script 的版權宣告方式;
- script 的 History (歷史紀錄);
- script 內較特殊的指令,使用『絕對路徑』的方式來下達;
- script 運作時需要的環境變數預先宣告與設定。
三.编写shell script
①hello world
- 第一行 #!/bin/bash 在宣告這個 script 使用的 shell 名稱:
因為我們使用的是 bash ,所以,必須要以『 #!/bin/bash 』來宣告這個檔案內的語法使用 bash 的語法!那麼當這個程式被執行時,他就能夠載入 bash 的相關環境設定檔 (一般來說就是 non-login shell 的 ~/.bashrc), 並且執行 bash 來使我們底下的指令能夠執行!這很重要的!(在很多狀況中,如果沒有設定好這一行, 那麼該程式很可能會無法執行,因為系統可能無法判斷該程式需要使用什麼 shell 來執行啊!)
- 程式內容的說明:
整個 script 當中,除了第一行的『 #! 』是用來宣告 shell 的之外,其他的 # 都是『註解』用途! 所以上面的程式當中,第二行以下就是用來說明整個程式的基本資料。一般來說, 建議你一定要養成說明該 script 的:1. 內容與功能; 2. 版本資訊; 3. 作者與聯絡方式; 4. 建檔日期;5. 歷史紀錄 等等。這將有助於未來程式的改寫與 debug 呢!
- 主要環境變數的宣告:
建議務必要將一些重要的環境變數設定好,鳥哥個人認為, PATH 與 LANG (如果有使用到輸出相關的資訊時) 是當中最重要的! 如此一來,則可讓我們這支程式在進行時,可以直接下達一些外部指令,而不必寫絕對路徑呢!比較方便啦!
- 主要程式部分
就將主要的程式寫好即可!在這個例子當中,就是 echo 那一行啦!
- 執行成果告知 (定義回傳值)
是否記得我們在第十章裡面要討論一個指令的執行成功與否,可以使用 $? 這個變數來觀察~ 那麼我們也可以利用 exit 這個指令來讓程式中斷,並且回傳一個數值給系統。 在我們這個例子當中,鳥哥使用 exit 0 ,這代表離開 script 並且回傳一個 0 給系統, 所以我執行完這個 script 後,若接著下達 echo $? 則可得到 0 的值喔! 更聰明的讀者應該也知道了,呵呵!利用這個 exit n (n 是數字) 的功能,我們還可以自訂錯誤訊息, 讓這支程式變得更加的 smart 呢!
②变量使用
1.简单的输入
2.随日期变化
③数值运算
可以利用『 $((計算式)) 』來進行數值運算:var=$((運算內容))。注意有2层括号
bc指令可以协助计算
四.不同script执行时候的差异
①直接执行方式执行的script
接指令下達 (不論是絕對路徑/相對路徑還是 ${PATH} 內),或者是利用 bash (或 sh) 來下達腳本時, 該 script 都會使用一個新的 bash 環境來執行腳本內的指令!也就是說,使用這種執行方式時, 其實 script 是在子程序的 bash 內執行的!
重點在於:『當子程序完成後,在子程序內的各項變數或動作將會結束而不會傳回到父程序中』
②利用source来执行脚本:在父程序中执行
五.判断表达式
①test指令
②判断符号[]
要在 bash 的語法當中使用中括號作為 shell 的判斷式時,必須要注意中括號的兩端需要有空白字元來分隔喔! 假設我空白鍵使用『□』符號來表示,那麼,在這些地方你都需要有空白鍵:
- 在中括號 [] 內的每個元件都需要有空白鍵來分隔;
- 在中括號內的變數,最好都以雙引號括號起來;
- 在中括號內的常數,最好都以單或雙引號括號起來。
六.shell script 的预设变量
①基本使用
- $# :代表後接的參數『個數』,以上表為例這裡顯示為『 4 』;
- "$@" :代表『 "$1" "$2" "$3" "$4" 』之意,每個變數是獨立的(用雙引號括起來);
- "$*" :代表『 "$1c$2c$3c$4" 』,其中 c 為分隔字元,預設為空白鍵, 所以本例中代表『 "$1 $2 $3 $4" 』之意。
例子:
- 程式的檔名為何?
- 共有幾個參數?
- 若參數的個數小於 2 則告知使用者參數數量太少
- 全部的參數內容為何?
- 第一個參數為何?
- 第二個參數為何
②shift
光看結果你就可以知道啦,那個 shift 會移動變數,而且 shift 後面可以接數字,代表拿掉最前面的幾個參數的意思。 上面的執行結果中,第一次進行 shift 後他的顯示情況是『 one two three four five six』,所以就剩下五個啦!第二次直接拿掉三個,就變成『 two three four five six 』。
七.条件判断式
①if
- && 代表 AND ;
- || 代表 or ;
比如:
[ "${yn}" == "Y" -o "${yn}" == "y" ]
上式可替換為
[ "${yn}" == "Y" ] || [ "${yn}" == "y" ]
让用户输入“hello”这个参数:
②case-esac
一般來說,使用『 case $变量 in 』這個語法中,當中的那個『 $变量 』大致有兩種取得的方式:
- 直接下達式:例如上面提到的,利用『 script.sh variable 』 的方式來直接給予 $1 這個變數的內容,這也是在 /etc/init.d 目錄下大多數程式的設計方式。
- 互動式:透過 read 這個指令來讓使用者輸入變數的內容。
八.函数function
因為 shell script 的執行方式是由上而下,由左而右, 因此在 shell script 當中的 function 的設定一定要在程式的最前面
九.循环loop
①不定次数的循环
當 condition 條件成立時,就進行迴圈,直到 condition 的條件不成立才停止
當 condition 條件成立時,就終止迴圈, 否則就持續進行迴圈的程式段。
从1加到100
②定次数循环
1.第一种写法
参数的第一种表达方法
参数的第二种表达方法
就会一个栏位一个栏位地显示
参数的第三种表达方法
2.第二种写法
- 初始值:某個變數在迴圈當中的起始值,直接以類似 i=1 設定好;
- 限制值:當變數的值在這個限制值的範圍內,就繼續進行迴圈。例如 i<=100;
- 執行步階:每作一次迴圈時,變數的變化量。例如 i=i+1。