話不多說,直接開車
在編寫shell腳本中,我們經常需要判斷命令執行的正確與否,從而進行不同的操作。首先我們來介紹下條件性的執行操作符:根據退出狀態而定,命令可以有條件地運行。其中,利用echo的話方便我們對測試結果的查看。
(1)&& 代表條件性的AND THEN
可以理解為短路與:當&&前面命令為真時,執行&&符號后的內容。當前面命令為假,不執行&&后面的內容。
[root@localhost ~]#cd /etc/ && echo true true [root@localhost etc]#cd /etc123/ && echo true -bash: cd: /etc123/: No such file or directory
[root@localhost etc]#cd /etc123/ 2> /dev/null && echo true #將錯誤輸出定向到黑洞(/dev/null)里面 [root@localhost etc]#
(2)|| 代表條件性的OR ELSE
可以理解為短路或:當||前面命令為真時,不執行||符號后的內容。當前面命令為假,執行||后面的內容。
[root@localhost etc]#cd /etc/ || echo false [root@localhost etc]# [root@localhost etc]#cd /etc123/ 2> /dev/null || echo false false
兩者可以結合判斷顯示,更加直觀:
[root@localhost etc]#cd /etc/ && echo ture || echo false ture #cd /etc/ 命令為真,執行&&后面的內容,不再去管||符號 [root@localhost etc]#cd /etc123/ 2> /dev/null && echo ture || echo false false #cd /etc/ 命令為假,不執行&&后面的內容,跳到執行||后面內容。
雖然對于命令可以直接判斷執行正確或錯誤,但許多情況下無法直接用命令解決,于是,鐺鐺鐺鐺鐺,出現了測試命令,Linux的Shell中存在一組測試命令,該組命令用于測試某種條件或某幾種條件是否真實存在。測試命令是判斷語句和循環語句中條件測試工具,對于編寫Shell非常重要。
測試命令用于測試表達式的條件的真假。如果測試的條件為真,則返回一個0值;如果測試條件為假,將返回一個非0整數值。
測試命令有兩種結構,一種是用test命令進行測試,結構如下:
test expression
其中,條件expression是一個表達式,該表達式可為數字、字符串、文本和文件屬性的比較,同時可同時加入各種算術、字符串、文本等運算符。
為了提高命令的可讀性,經常使用第二種格式:
[ expression ]
其中“[”是啟動測試命令,但要求在expression后要有一個“]”與其配對。使用該命令要特別注意“[”后和“]”前的空格必不可少。第二種格式常用。
兩類測試命令
Test :如:
[root@localhost ~]#A=123 #定義變量 [root@localhost ~]#B=0123 #定義變量 [root@localhost ~]#test "$A" == "$B" && echo true || echo false false [root@localhost ~]#test "$A" -eq "$B" && echo true || echo false true
[ :如
[root@localhost ~]#[ "$A" == "$B" ] && echo true || echo false false [root@localhost ~]#[ "$A" -eq "$B" ] && echo true || echo false true #注意“[”后和“]”前的空格必不可少,這種格式比較常用
常用表達式:
-v VAR
變量VAR是否設置,設置為真
[root@localhost ~]#A=123 [root@localhost ~]#[ -v A ] && echo true || echo false true [root@localhost ~]#[ -v a ] && echo true || echo false false
#字符串比較
== :字符串是否相等
> :前者ASCII碼是否大于后者ASSCII碼
< :前者ASCII碼是否小于后者ASSCII碼
!= :字符串是否不相等
=~ :左側字符串是否能夠被右側的PATTERN所匹配
注意:此表達式一般用于[[]]中;擴展的正則表達式的PATTERN(模式)
[root@localhost ~]#[[ "123456" =~ [0-9]{6} ]] && echo ture || echo false ture [root@localhost ~]#[[ "123456" =~ [0-9]{7} ]] && echo ture || echo false false #注意:擴展正則表達式不需要加雙引號
-n :string檢查字符串長度不為0(等價test string)
-z :string檢查字符串長度為0
[root@localhost ~]#[ -n "abc" ] && echo ture || echo false ture [root@localhost ~]#test "abc" && echo ture || echo false ture [root@localhost ~]#test "" && echo ture || echo false false [root@localhost ~]#[ -n "" ] && echo ture || echo false false [root@localhost ~]#[ -n " " ] && echo ture || echo false ture
[root@localhost ~]#A= #定義A變量,不輸入任何字符,直接回車 [root@localhost ~]#[ -n "$A" ] && echo ture || echo false false
注意:用于字符串或者引用變量比較時的用到的操作數都應該使用雙引號
#數字比較
int1 -eq int2 int1等于int2
int1 -ne int2 int1不等于int2
int1 -ge int2 int1大于等于int2
int1 -gt int2 int1大于int2
int1 -le int2 int1小于等于int2
int1 -lt int2 int1小于int2
[root@localhost ~]#A=0123 [root@localhost ~]#B=123 [root@localhost ~]#[ "$A" -eq "$B" ] && echo true || echo false true [root@localhost ~]#[ "$A" -ge "$B" ] && echo true || echo false true [root@localhost ~]#[ "$A" -ne "$B" ] && echo true || echo false false
#文件比較
file1 -ef file2 文件的設備和節點號相同
file1 -nt file2 file1比file2的新(修改日期)
file1 -ot file2 file1比file2的舊(修改日期)
[root@localhost mnt]#cp /etc/passwd . #拷貝文件放到當前目錄 [root@localhost mnt]#ln passwd mima #設置硬鏈接,硬鏈接本質就像一個文件多個文件名,文件的本質(節點號)一樣,只是文件名不同而已。 [root@localhost mnt]#ls mima passwd [root@localhost mnt]#[ passwd -ef mima ] && echo true || echo false true [root@localhost mnt]#touch file1 file2 #同時創建文件 [root@localhost mnt]#stat file1 file2 #查看文件時間戳,包括修改時間Modify ................ [root@localhost mnt]#touch -m file2 #touch -m 僅僅更新文件的修改時間 [root@localhost mnt]#stat file1 file2 ................ [root@localhost mnt]#[ file1 -nt file2 ] && echo true || echo false false [root@localhost mnt]#[ file1 -ot file2 ] && echo true || echo false true
#文件判斷
-b filename | 當filename 存在并且是塊文件時返回真(返回0) |
-c filename | 當filename 存在并且是字符文件時返回真 |
-d pathname | 當pathname 存在并且是一個目錄時返回真 |
-e pathname | 當由pathname 指定的文件或目錄存在時返回真 |
-f filename | 當filename 存在并且是正規文件時返回真 |
-g pathname | 當由pathname 指定的文件或目錄存在并且設置了SGID 位時返回真 |
-h filename | 當filename 存在并且是符號鏈接文件時返回真 (或 -L filename) |
-k pathname | 當由pathname 指定的文件或目錄存在并且設置了”粘滯”位時返回真 |
-p filename | 當filename 存在并且是命名管道時返回真 |
-r pathname | 當由pathname 指定的文件或目錄存在并且可讀時返回真 |
-s filename | 當filename 存在并且文件大小大于0 時返回真 |
-S filename | 當filename 存在并且是socket 時返回真 |
-t fd | 當fd 是與終端設備相關聯的文件描述符時返回真 |
-u pathname | 當由pathname 指定的文件或目錄存在并且設置了SUID 位時返回真 |
-w pathname | 當由pathname 指定的文件或目錄存在并且可寫時返回真 |
-x pathname | 當由pathname 指定的文件或目錄存在并且可執行時返回真 |
-O pathname | 當由pathname 存在并且被當前進程的有效用戶id 的用戶擁有時返回真(字母O 大寫) |
-G pathname | 當由pathname 存在并且屬于當前進程的有效用戶id 的用戶的用戶組時返回真 |
最后說一下組合測試:
第一種方式:
COMMAND1 && COMMAND2 邏輯關系:并且
COMMAND1 || COMMAND2 邏輯關系:或者
! COMMAND 邏輯關系:非
EXPRESSION1 && EXPRESSION2 邏輯關系:并且
EXPRESSION1 || EXPRESSION2 邏輯關系:或者
! EXPRESSION 邏輯關系:非
如:
[root@localhost app]#( cd /etc/ && cd /app/ 2> /dev/null ) && echo true || echo false true [root@localhost app]#( cd /etc/ && cd /app123/ 2> /dev/null ) && echo true || echo false false [root@localhost app]#([[ -n "123" ]] && [[ -n "" ]]) && echo true || echo false false [root@localhost app]#([[ -n "123" ]] && [[ -n "123" ]]) && echo true || echo false true
第二種方式:必須使用測試命令進行
EXPRESSION1 -a EXPRESSION2 邏輯關系:并且
EXPRESSION1 -o EXPRESSION2 邏輯關系:或者
! EXPRESSION 邏輯關系:非
如:
[root@localhost app]#[ -n "123" -a -n "12" ] && echo ture || echo false ture [root@localhost app]#[ -n "123" -a -n "" ] && echo ture || echo false false [root@localhost app]#[ -n "123" -o -n "" ] && echo ture || echo false ture
原創文章,作者:Mozart,如若轉載,請注明出處:http://www.www58058.com/83716