標籤:linux shell case if
流程式控制制可根據不同的情況做不同的處理,而且可重複執行指定的程式地區,展現程式的生產力。在Bash Shell中,流程式控制制可以分為兩大類:
“選擇”和“迴圈”;
1、選擇:if、case、select
2、迴圈:for、while、until、select
命令select既屬選擇也屬於迴圈。
一、命令的結束狀態
在Shell中每一個命令執行後,都會傳回一個結束狀態值,只分兩種,如果成功,傳回0,失敗則傳回非0.
當命令執行後,用$?來查看狀態傳回值,當在Shell進行條件測試的時候$?=0為真,$?=非0為假。
[[email protected] ~]# pwd/root[[email protected] ~]# echo $?0[[email protected] ~]# pwdddd-bash: pwdddd: command not found[[email protected] ~]# echo $?127
當一個命令正常執行的時候,$?=0.當一個命令輸入錯誤的時候,$?=非0
比如yum安裝軟體、複製檔案、刪除檔案、判斷檔案是否存在等..如果正確執行,則$?=0,如果中間出錯,$?=非0
二、if條件判斷
if 條件測試;then
命令地區
fi
如果"條件測試"為真,就執行"命令地區"的指令,否則繼續fi下一行指令。
[[email protected] ~]# cat test.sh #!/bin/bash#if grep -q ^root /etc/passwd;thenecho "The user root is exist"fi[[email protected] ~]# bash test.sh The user root is exist
使用grep在/etc/passwd搜尋以root開頭的關鍵詞,如果為真,就繼續執行下邊的命令(grep -q表示只判斷真假,不作輸出)。
最簡單的if文法:if-then-else
if 條件測試;then
命令地區1
else
命令地區2
fi
如果"條件測試"為真,就執行"命令地區1"的指令,否則就執行"命令地區2"的指令。
[[email protected] ~]# cat test.sh #!/bin/bash#if grep -q ^roothi /etc/passwd;thenecho "The user roothi is exist"elseecho "The user roothi not exist"fi[[email protected] ~]# bash test.sh The user roothi not exist
判斷使用者roothi是否存在。
if的完整文法
if 條件測試1;then
命令地區1
elif 條件測試2;then
命令地區2
else
命令地區3
fi
如果條件測試1為真,則執行命令地區1,如果為假,則執行條件測試2;如果條件測試2為真,則執行命令地區2,如果條件測試2為假,則執行命令地區3(elif條件可以有多個)。
[[email protected] ~]# ./test.sh 5 25 is the bigger![[email protected] ~]# ./test.sh 5 1010 is the bigger![[email protected] ~]# ./test.sh 5 55 = 5 [[email protected] ~]# cat test.sh #!/bin/bash#declare -i a b #聲明a b都在正整數a=$1b=$2if (( $a > $b ));thenecho $a is the bigger!elif (( $a < $b ));thenecho $b is the bigger!elseecho "$a = $b "fi
三、條件測試的寫法
條件測試的寫法有10種。(傳回結果0為真值,非0為假值)
1、執行某一個命令的結果。
if grep -q "root" /etc/passwd;then (-q 靜默,只為判斷$?)
echo "root is exist"
其結束狀態為最後一個命令執行的結果
2、傳回某一命令結果的相反值。
! 命令(中間要用空格隔開)
if ! grep -q "root" /etc/passwd;then (-q 靜默,只為判斷$?)
echo "root is not exist"
如果命令傳回結果為0,則加上!之後傳回值為1;反之如果命令傳回值為非0,則加上!之後傳回值為0
3、使用複合命令((算式))
運算結果不為0為真,為0為假
((8*3)) 24 真
((5-5)) 0 假
((20<30)) 真
((20>30)) 假
((20&&30)) 真
((20&&0)) 假
4、使用Bash關鍵字‘[[ ]]‘組成的句子:[[ 判斷式 ]]
[[ 後和 ]]前至少有一個空格
if [[ str > xyz ]];then
echo "字串str比較大"
5、使用內建命令:test判斷式
if test "str" \> "xyz";then (>為特殊字元,用\轉義)
echo "字串str比較大"
6、使用內建命令:[ ]判斷式
[] 與test用法相同
if [ "str" \> "xyz" ];then (>為特殊字元,用\轉義)
echo "字串str比較大"
7、使用-a、-o進行邏輯組合
[ -r filename -a -x filename] 如果filename可讀且可執行,則為真。-a,且。
[ -r filename -o -x filename] 如果filename可讀或可執行,則為真。-o,或。
8、命令1&&命令2
命令1真才執行命令2,都真傳回值0,否則1
if grep -q "root" /etc/passwd && ((8<10));then
9、命令1||命令2
命令1假才執行命令2,如果一個命令或都為真傳回值0,否則1
((2<3))||((4<5));then
10、$$和||合用
如果是 “[ 判斷式 ] &&指令1||指令2”形式,視為 if-then-else
[ "2" \> "1" ]&& echo "right"||echo "error"等同於等同於以下指令碼:
if [ "2" \> "1" ];then
echo "right"
else
echo "error"
fi
總結:
[[ ]]、test、[]用法意思相近,但[[ ]]更自由(不必擔心特殊符號,不必轉義),(())也不受特殊符號影響。
在[[判斷式]]中,如果使用==或!=且右方的字串沒有使用單引號、雙引號,則視為對比該字串形成的“樣式”,如果相符,傳回0,否則1。
!/bin/bash
a="str"
if [[ $a == ??? ]];then 意思是:用$a的值,對比樣式???(3個字串)
echo "hello"
fi
上邊如果把if行改為
if [[ $a == "???" ]];then 意思是:用$a和字串???是否相等
四、條件判斷式的真假值
判斷式:影響程式流程的式子,判斷式分為“單元”和“二元”
如 -f filename ,測試檔案是否存在。-f後跟一個運算元的檔案稱為“單元”。
如 參數1 -gt 參數2,測試參數1值是否大於參數2,-gt左右各接一個要比較的參數,這種判斷式稱為“二元”。
--------------------關於檔案的判斷式--------------------
判斷式 什麼情況下為真
-a/e 檔案存在
-b 檔案存在,且檔案是地區裝置檔案
-c 檔案存在,且檔案是字元裝置檔案
-d 檔案存在,且檔案是目錄
-p 檔案存在,且該檔案是管道檔案(FIFO)
-f 檔案存在,且該檔案是一般檔案
-g 檔案存在,且該檔案設立了 set group id屬性 -u uid
-h/L 檔案存在,且該檔案是符號連結檔案
-r 檔案存在,且該檔案有可讀取的屬性 -w 可寫 -x 可執行
-s 檔案存在,且該檔案大小大於0(檔案存在,且檔案有資料)
-t 檔案描述符 如果檔案描述符是開啟的,且連結了某一個終端
-S 檔案存在,且該檔案是socket檔案
-N 檔案存在,且該檔案從上次讀取後,曾修改過。
檔案1 -nt 檔案2 如果檔案1比檔案2新;檔案1存在,但檔案2不存在。
檔案1 -ot 檔案2 如果檔案1比檔案2舊;檔案1不存在,但檔案2存在。
檔案1 -ef 檔案2 如果檔案1和檔案2 參考到相同的裝置和inode編號。
--------------------關於字串的條件判斷式--------------
判斷式 什麼情況下為真
-z 長度為0(即Null 字元串)
-n 長度不為0(即非Null 字元串)
字串字串長度不為0
==和=代表相同(左右兩邊分別有個字串)
!= 不等 < 小於 > 大於 (如果<>出現在[]或test中的時候,要用\轉義)
--------------------關於算式的條件判斷式----------------
-eq 相等
-ne 不相等
-lt 小於
-le 小於或等於
-gt 大於
-ge 大於或等於
-------------------關於Bash選項的條件判斷式-------------------
-o set選項的名稱 如果該選項為開啟狀態則為真。
!/bin/bash
set -o
if [ -o history ];then
echo ‘Bash選項history開啟‘
else
echo ‘Bash選項history關閉‘
fi
五、case條件判斷
if條件判斷中提到的if條件判斷,一旦要進行的條件測試的情況多了起來,if和elif的文法就會變得很冗長,case條件判斷文法可補其不足。
------------------case的文法結構------------------
case 待測項 in
樣式串列1 )命令地區1;;
樣式串列2 )命令地區2;;
樣式串列3 )命令地區3;;
.....
*) 命令地區;;
esca
樣式串列可以是字串:如a、b、mary
萬用字元:*任意長度(包括Null 字元) ?一個字元
字元集合:[a-d]mm,表示amm、bmm、cmm、dmm
分隔字元:|
如果待測項與樣式串列符合的話,case會執行該樣式後的命令地區,命令地區可以是單一指令或多行指令,最後以;;結束。
樣式串列可以用字串和萬用字元組成,預設會區別大小寫。
如果串列有好幾個字元要對比,用|隔開,|有或的意思(只要符合其中之一就算成功)。
樣式串列可以寫為‘(樣式串列)‘或‘樣式串列‘
*)通常放在case最後的一個地區,用來譜捉不符合指定樣式的其它情況。
例子:
!/bin/bash
name=$1 第一個輸入的參數附給name
case $name in
a|b|c) 匹配的選項1,變數為a或b或c的時候
echo "hello,abc group" 輸出結果1
;; ;;可放到輸出結果1後,也可另起一行
huan) 匹配選項2 ,變數為huan的時候
echo "i love you" 輸出結果2
;;
s*) 匹配選項3,變數以s開頭的字串
echo "you are first s" 輸出結果3
;;
*) 匹配選項4 不符合上邊任何條件的字串
echo "what is this?";; 輸出結果4 "what is this?".......
esca 結束
-----------------進階樣式--------------------
樣式 符合情況
?(樣式串列) 符合0個或1個
*(樣式串列) 符合0個以上
+(樣式串列) 符合1個以上
@(樣式串列) 符合其中1個
!(樣式串列) 只要不是出現在括弧裡的樣式就算符合
[email protected](ac|xy|pq)k|join|joe echo ‘hello‘;;
只要變數符合jack、jxyk、jpqk、join、joe其中之一就算符合
if [[ $cmd == @(a|b) ]];then
只要是a或b就算是對比成功。
本文出自 “Welcome To Linux World” 部落格,請務必保留此出處http://linuxnote.blog.51cto.com/9876511/1641204
Linux Shell之五 流程式控制制--選擇