1. 程式人生 > >shell指令碼 if的使用和判斷條件

shell指令碼 if的使用和判斷條件

目錄

IF使用基礎

單分支語句結構

雙分支語句結構

 多分支語句結構

條件表示式

檔案表示式

數字表達式

字串表示式

&&  ||使用

test與[  ]

[  ]  與[[  ]]


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 ...] 不一樣,[[ ]] 是邏輯短路操作,而 [ ] 不會進行邏輯短路