在Bash Shell中,流程控制命令有兩大類:選擇和循環。屬於選擇的有:if、case;屬於循環的有:for、while、until;命令select既屬於選擇,也屬於循環。本文主要對選擇if的使用進行簡單的介紹。
Bash腳本可以由許多命令組成。每一個命令執行後,都會傳回一個結束狀態值。如果執行成功,返回0;如果執行失敗,則返回非0值。執行失敗,分為多種情況,例如:某個命令執行失敗,產生嚴重的信號n,則其結束狀態返回值為128+n。如果執行命令時,該命令不存在,則返回值為127。命令存在但沒有執行權限,則返回126。
Bash的內置變量$?用來存儲每個命令執行後傳回的狀態值。如下代碼所示:
# noexe.sh
noexe.sh: command not found
# echo $?
127
# ./noexe.sh
bash: ./noexe.sh: Permission denied
# echo $?
126
Bash的流程控制,需進行條件測試,就是以結束狀態作為真假值的判斷依據:如果結束狀態為0,則判斷為值;反之,如果結束狀態為非0值,則判斷為假。
最簡單的if條件判斷有以下兩種:
if-then
01. if 條件測試; then
02. 命令區域
03. fi
說明:如果「條件測試」為真,則執行「命令區域」的指令;否則,繼續執行fi後的下一條指令。
例如:
if (( 2 < 10 )); then
echo '真';
fi
如果2小於10的判斷為真,則顯示「真」。
if-then-else
01. if 條件測試; then
02. 命令區域1
03. else
04. 命令區域2
05. fi
說明:如果「條件測試」為真,則執行「命令區域1」的指令;否則,執行「命令區域2」的指令。
例如:
if [ -d /root/tmp ]; then
echo '/root/tmp目錄存在'
else
echo '/root/tmp目錄不存在'
fi
解釋:
行1,使用[ ]做條件測試,-d檢測/root/tmp目錄是否存在;
行2,如果判斷為真,則顯示目錄存在的信息;
行4,如果判斷為假,則顯示目錄不存在的信息。
if條件判斷的完整語法結構如下所示:
01. if 條件測試1; then
02. 命令區域1
03. elif 條件測試2; then
04. 命令區域2
05. else
06. 命令區域3
07. fi
說明:其中elif可以有多行,但是else只能有一行。「條件測試」如果和then放在同一行,需要用;隔開。條件測試1為真,則執行命令區域1的指令;條件測試2為真,則執行命令區域2的指令;否則執行命令區域3的指令。一般把「條件測試」和then寫在同一行。
示例比較代碼如下(test1.sh):
#! /bin/bash
declare -i a a
a=$1; b=$2
if (( a < b )); then
echo '$a小於$b'
elif (( a > b)); then
echo '$a大於$b'
else
echo '$a等於$b'
fi
解釋:
行2,聲明兩個整形變量a和b;
行3,變量a和b分別取值命令行參數1和2;
行4,如果a<b為真,則其結果為1,因此結束狀態傳回0;反之,傳回1。注意:(())和then之間要用;隔開,否則出現語法錯誤。
(( ))是Bash的複合命令,內置算式。((算式))可對算式的運算結果傳回真假值:如果算式的結果非0,則結束狀態傳回0,表示該算式為真;如果算式結果為0,則結束狀態傳回1,表示該算式為假。它的意義等同於:let "算式"。注意算式兩側的雙引號不可少。
例如:
#! /bin/bash
if grep -q "rm" test1.sh; then
echo 'find rm command.'
else
echo 'not find.'
fi
說明:
其形式為:! 命令
注意:!和命令之間要有空格符隔開。
如果命令傳回值為0,則加上!之後傳回值為1;反之,如果命令傳回值為非0,則加!之後,傳回值為0。
例如上述2.1例子中,可以修改為「if ! grep -q "rm" test1.sh; then」,這樣就是如果test1.sh文件中找不到rm關鍵字,就傳回0(真值),否則傳回1(假值)。
如果算式的運算結果不為0,則傳回真值(0),否則如果運算結果為0,則返回假值(1)。
算式範例如下圖所示:
判斷式會傳回真假值,傳回0為真,傳回非0為假。
注意:[[ 的後面、 ]]的前面,都至少有一個或以上的空格符才行。
例如:
#! /bin/bash
if [[ str > xyz ]]; then
echo '字符串str較大'
else
echo '字符串xyz較大'
fi
其形式為:[ 判斷式 ]
例如:
#! /bin/bash
if [ str \> xyz ]; then
echo '字符串str較大'
else
echo '字符串xyz較大'
fi
要特別注意:大於符號>對Bash而言是特殊字符,需要使用\進行轉義。
用例:
[ -r filename1 -a -x filename ]
說明:如果filename1可讀且可執行,則為真。-a即「且」之意。
[ -r filename1 -o -x filename ]
說明:如果filename1可讀或可執行,則為真。-o即「或」之意。
形式為:命令1 && 命令2 、命令1 || 命令2。
含義分別為:&&稱為邏輯AND,如果命令1執行結果為真,才會執行命令2;如果兩個都為真,則傳回真值0,否則傳回假值1。||稱為邏輯OR,如果命令1執行結果為假,才會執行命令2,如果兩個之後有一個為真,則傳回真值0,否則傳回假值1。
小結:在上述條件測試的方法中,[[]]和[]的意思和用法相近,但是[[]]比[]使用更自由一點。因為[[]]不必擔心某些Bash特殊字符對運算符的影響。不必寫很多轉義字符。但在[]中,對於>,<,&&,||等都要使用轉義字符\進行轉義才行。除了[[]]之外,在Bash中(())也不必理會上述的特殊字符的影響。另外在[[]]中,如果使用==和!=進行比較,且在這兩個運算符右側的字符串沒有使用單引號或雙引號,則==和!=會視為對比該字符串所形成的「樣式」,如果相符,傳值為0,否則不符,傳回1。
①複製「Linux腳本之家或LinuxSheller」,在「添加朋友」中粘貼搜索號碼關注。
②點擊微信右上角的「+」,會出現「添加朋友」,進入「查找公眾號」,輸入以下公眾號的名字,即可找到。