1. 程式人生 > >shell 的條件表達式及邏輯操作符簡單介紹

shell 的條件表達式及邏輯操作符簡單介紹

col 簡單介紹 目錄 特殊 文件 html 需要 != 空格

查看系統的shell:

cat /etc/shells

文件測試表達式:

  -f 文件 文件存在且為普通文件則真,即測試表達式成立。

  -d 文件 文件存在且為目錄文件則真,即測試表達式成立。

  -s 文件 文件存在且文件大小不為0則真,即測試表達式成立。

  -e 文件 文件存在則真,即測試表達式成立。只要有文件就行,要區別 -f 。

  -r 文件 文件存在且可讀則真,即測試表達式成立。

  -w 文件 文件存在且可寫則真,即測試表達式成立。

  -x 文件 文件存在且可執行則真,即測試表達式成立。

  -L 文件 文件存在且為鏈接文件則真,即測試表達式成立。

  a –nt b 文件a比文件b新則真,即測試表達式成立,根據文件修改時間來計算

  a –nt b 文件a比文件b舊則真,即測試表達式成立,根據文件修改時間來計算

特別說明:這些操作符號對於[[]]、[]、test幾乎是通用的,更多的操作符請man test查詢。

普通文件測試表達式:

[root@lamp01 ~]# mkdir bqh1
[root@lamp01 ~]# ll -d ./bqh1
drwxr-xr-x. 2 root root 4096 1月  27 21:51 ./bqh1
[root@lamp01 ~]# [ -d bqh1 ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -f bqh1.log ]&&echo 1||echo 0
0
[root@lamp01 ~]# touch ./bqh1.log
[root@lamp01 ~]# [ -f bqh1.log ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -e bqh1.log ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -e bqh2.log ]&&echo 1||echo 0
[root@lamp01 ~]# [ -r bqh1 ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -w bqh1 ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -x bqh1 ]&&echo 1||echo 0
1
[root@lamp01 ~]# chmod 000 bqh1
[root@lamp01 ~]# ll
d---------. 2 root root  4096 1月  27 21:51 bqh1
[root@lamp01 ~]# [ -x bqh1 ]&&echo 1||echo 0
1

提示:文件的讀寫執行等屬性,不光是根據文件屬性,而是當前執行腳本的用戶根據測試選項是否真的可操作。

測試shell變量舉例:

[root@lamp01 ~]# a=/etc/services
[root@lamp01 ~]# b=/etc/
[root@lamp01 ~]# [ -f $a ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -d $a ]&&echo 1||echo 0
0
[root@lamp01 ~]# [ -d $b ]&&echo 1||echo 0
1

特殊例子:如果變量不加雙引號,測試結果可能不正確。

[root@lamp01 ~]# echo $c
[root@lamp01 ~]# [ -f "$c" ]&&echo 1||echo 0
0
[root@lamp01 ~]# [ -f $c ]&&echo 1||echo 0
1    #$c明明不存在的,卻返回1

使用條件表達式時,多個返回值時,可以使用大括號的用法,格式如下:

當條件不成立就會執行大括號內的所有命令內容:

[root@lamp01 ~]# [ 1 -ne 1 ]||{ echo "my name is bqh" ; echo "my name is jyw" ;}
my name is bqh
my name is jyw
[root@lamp01 ~]# 

字符串測試表達式:

  字符串測試操作符:

  -z “字符串” 若串長度為0則真

  -n ”字符串“ 若串長度不為0則真

  “字符串1”=“字符串2” 若串1等於串2則真,可以使用‘==’代替‘=’

  “字符串1”!=“字符串2” 若串1不等於串2則真,但不能用‘!==’代替‘!=’

測試如下:

[root@lamp01 ~]# [ -n "abc" ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -n "" ]&&echo 1||echo 0
0
[root@lamp01 ~]# [ -z "" ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -z "abc" ]&&echo 1||echo 0
0
[root@lamp01 ~]# [ ! -z "abc" ]&&echo 1||echo 0
1
[root@lamp01 ~]# a="bqh"
[root@lamp01 ~]# [ -n "$a" ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -z $a ]&&echo 1||echo 0
0
[root@lamp01 ~]# [ ! -z $a ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ "$a" != "bqh1" ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ "$a" = "bqh1" ]&&echo 1||echo 0
0

等號兩端空格帶來的問題:

[root@lamp01 ~]# [ "abc"="1" ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ "abc" = "1" ]&&echo 1||echo 0
0

不加引號帶來的問題:

[root@lamp01 ~]# a=""
[root@lamp01 ~]# [ $a = abc  ]&&echo 1||echo 0
-bash: [: =: unary operator expected
0
[root@lamp01 ~]# [ $a = "abc"  ]&&echo 1||echo 0
-bash: [: =: unary operator expected
0
[root@lamp01 ~]# [ "$a" = "abc"  ]&&echo 1||echo 0
0
[root@lamp01 ~]# 

特別註意:

1.比較符合兩端有空格。

2.字符串測試操作符號務必要用“”引起來。

整數表達式:

  -eq: ==或= 測試兩個整數是否相等;比如 $A -eq $B

  -ne: != 測試兩個整數是否不等;不等,為真;相等,為假;

  -gt: > 測試一個數是否大於另一個數;大於,為真;否則,為假;

  -lt: < 測試一個數是否小於另一個數;小於,為真;否則,為假;

  -ge: >= 大於或等於

  -le: <= 小於或等於

在使用中中註意:

1、[]及test中使用字母模式。

2、在 (()) 和 [[]] 中使用符合模式。

提示:

“<”符號意思是小於,if[[ "$a" < "$b" ]],if [ "$a" \< "$b" ] 在單[]中需要轉義,因為shell也用<和>重定向。

“>”符號意思是大於,if[[ "$a" > "$b" ]],if [ "$a" \> "$b" ] 在單[]中需要轉義,因為shell也用<和>重定向。

“=”符號意思是等於,if[[ "$a" = "$b" ]],if [ "$a" = "$b" ] 在單[]中不需要轉義。

測試:

[root@lamp01 ~]# [ 2>1 ] && echo 1 || echo 0
0  ==>這裏的結果邏輯不對,條件應該成立,應該返回1
[root@lamp01 ~]# [ 2\>1 ] && echo 1 || echo 0
1 ==>轉義後是正確的
[root@lamp01 ~]# [ 2 -eq 1 ] && echo 1 || echo 0
0
[root@lamp01 ~]# [ 2 -gt 1 ] && echo 1 || echo 0
1
[root@lamp01 ~]# [ 2 -lt 1 ] && echo 1 || echo 0
0
[root@lamp01 ~]# [ 2 -ge 1 ] && echo 1 || echo 0
1
[root@lamp01 ~]# [ 2 -le 1 ] && echo 1 || echo 0
0
[root@lamp01 ~]# [ 2 = 1 ] && echo 1 || echo 0
0
[root@lamp01 ~]# [ 2 = 2 ] && echo 1 || echo 0
1
[root@lamp01 ~]# [ 2 != 2 ] && echo 1 || echo 0
0

“=” 和 “!=” 在[]中使用不需要轉義,包含“>”和“<”的符號在[]中使用需要轉義,對於數字不轉義的結果未必會報錯,但是結果可能會不對。

[root@lamp01 ~]# [[ 2 > 1 ]] && echo 1 || echo 0
1
[root@lamp01 ~]# [[ 2 > 11 ]] && echo 1 || echo 0 ====>只比較第一位,邏輯結果不對。
1
[root@lamp01 ~]# [[ 2 > 31 ]] && echo 1 || echo 0 ====>只比較第一位,邏輯結果不對。
0

數比較不要加雙引號:系統腳本例子

技術分享圖片

整數比較推薦方法:

[ $numl -eq $num2 ] ===>註意空格,和比較符號

(($num1>$num2)) ===>無需空格,常規數據比較符號。

--------------------------------------------------------------------------------------------------------

測試結果結論:

1、整數加雙引號也是對的。

2、[]用>號的寫法語法沒錯,邏輯結果不對。

3、[[]]用-eq等的寫法也是對的,[[]]用>寫法也可能不對,只比較第一位,邏輯結果不對。

邏輯操作符

在[]和test中使用 在[[]]中使用 說明

-a && and與,兩端都為真,則真

-o || or或,兩端有一個真,則真

! ! not非,相反則為真

測試:

[root@lamp01 ~]# a1=/etc/rc.local
[root@lamp01 ~]# a2=/etc/services
[root@lamp01 ~]# [ -f "$a1" && -f "$a2" ]&&echo 1||echo 0
-bash: [: missing `]‘
0
[root@lamp01 ~]# [ -f "$a1" -a -f "$a2" ]&&echo 1||echo 0
1
[root@lamp01 ~]# [[ -f "$a1" && -f "$a2" ]]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -n "$a1" -a -z "$a2" ]&&echo 1||echo 0
0
[root@lamp01 ~]# [ -n "$a1" -o  "$a1"="$a2" ]&&echo 1||echo 0
1

如果你非要單中括號加&&或||可以用以下方法:

[root@lamp01 ~]# a1=/etc/rc.local
[root@lamp01 ~]# a2=/etc/services
[root@lamp01 ~]# [ -f "$a1" ]||[ -e "$a2" ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ -f "$a1" ]&&[ -e "$a2" ]&&echo 1||echo 0
1

!非邏輯符號:

[root@lamp01 ~]# [ -f "$a1" ]&&[ -e "$a2" ]&&echo 1||echo 0
1
[root@lamp01 ~]# [ ! -f "$a1" ]&&[ -e "$a2" ]&&echo 1||echo 0
0
[root@lamp01 ~]# test -f "$a1" -a -e "$a2" &&echo 1||echo 0
1
[root@lamp01 ~]# test !  -f "$a1" -a -e "$a2" &&echo 1||echo 0
0

提醒:

1、“-a” 和 “-o” 和“!”邏輯操作符號用於 [] 中使用。

2、“&&”和“||” 和“!”邏輯操作符號用戶 [[]] 中使用。

3、註意括號兩端,必須要有空格。

4、test用法和 [] 相同。

5、多個[]之間以及多個[[]]之間,或者任意混合中間邏輯操作符都是&&或||。

shell 的條件表達式及邏輯操作符簡單介紹