shell指令碼 if的使用和判斷條件
目錄
IF使用基礎
單分支語句結構
if [ 條件表示式 ]; then
指令
fi
雙分支語句結構
if [ 條件表示式 ]; then
指令一
else
指令二
fi
多分支語句結構
if [ -f file ]; then echo "yes yes yes" elif [ -z file ]; then echo "yes yes" else echo "nonono" fi
注意 if的結構為 if then else fi
從上面三個結構中可以看出,條件表示式的左右,以及[ ]的左右都要有空格。
條件表示式
檔案表示式
檔案屬性 |
|
-a file |
如果file存在則為真 |
-b file |
如果file存在且為塊檔案則為真 |
-c file |
如果file存在且為字元檔案則為真 |
-d file |
如果file存在且是目錄則為真 |
-e file |
如果file存在則為真 |
-f file |
如果file存在且為普通檔案則為真 |
-g file |
如果file存在且置位設定-組ID則為真,見參考【1】第4.4、12.3節 |
-h file |
如果file存在且為符號連線則為真 |
-k file |
如果file存在且其粘性位置位則為真,參考man chmod |
-p file |
如果file存在且為命令管道(FIFO)則為真 |
-r file |
如果file存在且可讀則為真 |
-s file |
如果file存在且檔案長度大於0則為真 |
-t fd |
如果檔案描述符fd開啟且指向為終端則為真 |
-u file |
如果file存在且設定-使用者-ID置位則為真,見參考【1】第4.4節 |
-w file |
如果file存在且可寫則為真 |
-x file |
如果file存在且可執行 |
-G file |
如果file存在且由有效組ID擁有則為真,見參考【1】第4.4節 |
-L file |
如果file存在且為符號連線則為真 |
-N file |
如果file存在且在上次讀後有修改(modified)則為真 |
-O file |
如果file存在且由有效使用者ID擁有則為真,見參考【1】第4.4節 |
-S file |
如果file存在且是一個套接字則為真 |
file1 -ef file2 |
如果file1和file2指向同一個裝置的inode則為真 |
file1 -nt file2 |
如果file1比file新(modified),或者file1存在file2不存在在為真 |
file1 -ot file2 |
如果file1比file舊(modified),或者file1存在file2不存在在為真 |
-r file 使用者可讀為真
-w file 使用者可寫為真
-x file 使用者可執行為真
-f file 檔案為正規檔案為真
-d file 檔案為目錄為真
-c file 檔案為字元特殊檔案為真
-b file 檔案為塊特殊檔案為真
-s file 檔案大小非0時為真
-t file 當檔案描述符(預設為1)指定的裝置為終端時為真
數字表達式
int1 -eq int2 兩數相等為真
int1 -ne int2 兩數不等為真
int1 -gt int2 int1大於int2為真
int1 -ge int2 int1大於等於int2為真
int1 -lt int2 int1小於int2為真
int1 -le int2 int1小於等於int2為真
不要用=<>符號,如果要用的話
整數比較
-eq 等於,如:if [ "$a" -eq "$b" ]
-ne 不等於,如:if [ "$a" -ne "$b" ]
-gt 大於,如:if [ "$a" -gt "$b" ]
-ge 大於等於,如:if [ "$a" -ge "$b" ]
-lt 小於,如:if [ "$a" -lt "$b" ]
-le 小於等於,如:if [ "$a" -le "$b" ]
< 小於(需要雙括號),如:(("$a" < "$b"))
<= 小於等於(需要雙括號),如:(("$a" <= "$b"))
> 大於(需要雙括號),如:(("$a" > "$b"))
>= 大於等於(需要雙括號),如:(("$a" >= "$b"))
字串表示式
字串測試 |
|
-z string |
如果string長度為0則為真 |
string -n string |
如果string長度不為0則為真 |
string1 == string2 string1 = string2 |
如果string1和string2相等則為真,=只應由test使用 |
string1 != string2 |
如果字串不相等則為真 |
string1 < string2 |
如果按字典序string1在string2之前則為真 |
string1 > string2 |
如果按字典序string1在string2之後則為真 |
str1 = str2 當兩個串有相同內容、長度時為真
str1 != str2 當串str1和str2不等時為真
-n str1 當串的長度大於0時為真(串非空)
-z str1 當串的長度為0時為真(空串)
str1 當串str1為非空時為真
&& ||使用
在[ ]中不能用&& ||
要用
-a 與
-o 或
! 非
如
if [ $score -ge 0 -a $score -lt 60 ];
then echo "sorry,you are lost!"
elif [ $score -ge 60 -a $score -lt 85 ];
then echo "just soso!"
elif [ $score -le 100 -a $score -ge 85 ];
then echo "good job!"
else echo "input score is wrong , the range is [0-100]!"
fi
如果一定要用&& ||則要到[[ ]]中使用,
test與[ ]
格式1:test <測試表達式>
格式2:[<條件表示式>]
格式1和格式2是等價的。
test 一般在linux介面用,[ ]一般在if表示式用
如
1、測試檔案是否存在
[[email protected] ~]# test -f file&& echo 1||echo 0
0
[[email protected] ~]# touch file
[[email protected] ~]# test -f file&& echo 1||echo 0
1
[[email protected] ~]# test ! -f file&& echo 1||echo 0 取反
0
2、中括號
[[email protected] ~]# [ -f file ]&& echo 1||echo 0
1
[[email protected] ~]# rm file
[[email protected] ~]# [ -f file ]&& echo 1||echo 0
0
[[email protected] ~]# [ ! -f file ]&& echo 1||echo 0
1
[ ] 與[[ ]]
[[ ]],這是內建在shell中的一個命令,它就比剛才說的[ ]強大的多了。支援字串的模式匹配(使用=~操作符時甚至支援shell的正則表達 式)。簡直強大的令人髮指!邏輯組合可以不使用test的-a,-o而使用&&,||這樣更親切的形式(針對c、Java程式設計師)。
1. 首先,儘管很相似,但是從概念上講,二者是不同層次的東西。
"[[",是關鍵字,許多shell(如ash bsh)並不支援這種方式。ksh, bash(據說從2.02起引入對[[的支援)等支援。
"["是一條命令, 與test等價,大多數shell都支援。在現代的大多數sh實現中,"["與"test"是內部(builtin)命令,換句話說執行"test"/"["時不會呼叫/some/path/to/test這樣的外部命令(如果有這樣的命令的話)。
2.[[]]結構比Bash版本的[]更通用。在[[和]]之間的所有的字元都不會被檔案擴充套件或是標記分割,但是會有引數引用和命令替換。
用[[ ... ]]結構比用[ ... ]更能防止腳本里的許多邏輯錯誤。比如說,&&,||,<和>操作符能在一個[[]]測試裡通過,但在[]結構會發生錯誤。
3.[ ... ]為shell命令,所以在其中的表示式應是它的命令列引數,所以串比較操作符">" 與"<"必須轉義,否則就變成IO改向操作符了(請參看上面2中的例子)。在[[中"<"與">"不需轉義;
由於"[["是關鍵字,不會做命令列擴充套件,因而相對的語法就稍嚴格些。例如
在[ ... ]中可以用引號括起操作符,因為在做命令列擴充套件時會去掉這些引號,而在[[ ... ]]則不允許這樣做。
4.[[ ... ]]進行算術擴充套件,而[ ... ]不做
5.[[ ... && ... && ... ]] 和 [ ... -a ... -a ...] 不一樣,[[ ]] 是邏輯短路操作,而 [ ] 不會進行邏輯短路