天天看點

20.5-20.9 shel:l腳本中的邏輯判斷,檔案目錄屬性判斷,if特殊用法 ,case判斷

20.5 shell腳本中的邏輯判斷

不帶else

格式1:if 條件 ; then 語句; fi(這種格式常用)

解釋:

如果滿足條件,然後怎樣,最後怎樣

比較參數解釋:

  • eq EQ  EQUAL             等于
  • nq NQ  NOT EQUAL         不等于
  • gt GT  GREATER THAN        大于
  • lt LT  LESS THAN         小于
  • ge GE  GREATER THAN OR EQUAL   大于等于
  • le LE  LESS THAN OR EQUAL    小于等于

執行個體:

1 指令行形式表示

[root@AliKvn ~]# a=5
[root@AliKvn ~]# if [ $a -gt 3 ]
> then
> echo ok
> fi
ok
[root@AliKvn ~]# if [ $a -gt 3 ]; then echo ok; fi      

-gt 3 表示大于3

整條參數的意思就是,如果a大于3,顯示ok.

上面2條參數都是同樣效果,分開寫就用上面的格式,一條指令的格式就參考下面的。

2 腳本形式表示

編寫腳本

[root@AliKvn shell]# vim if1.sh
#!/bin/bash
a=5
if [ $a -gt 3 ]
then
    echo ok
fi      

執行

[root@AliKvn shell]# sh if1.sh
ok      

帶有else,表示否則。

格式2:if 條件; then 語句; else 語句; fi

解釋:如果滿足條件,然後怎樣;如果不滿足條件,然後怎樣。

1 編寫腳本

a=1,大于3就ok,否則,no.

[root@AliKvn shell]# vim if2.sh 
#!/bin/bash
a=1
if [ $a -gt 3 ]
then    
        echo ok
else 
        echo no
fi      

2 執行過程

[root@AliKvn shell]# sh -x if2.sh 

+ a=1a=1

+ '[' 1 -gt 3 ']'1與3比較,不滿足>3條件,

+ echo no但是滿足腳本中的else

no是以最後輸出結果是no

帶有elif,附件條件,同個腳本可以寫多個elif

格式3:if …; then … ;elif …; then …; else …; fi

[root@AliKvn shell]# vim if3.sh 
#!/bin/bash
a=3
if [ $a -gt 4 ]
then
        echo ">1"
elif [$a -gt 6]
then
        echo "<6 && >1"
else 
        echo no
fi      

參數解釋:

elif [$a -gt 6]而且a>6,

then

        echo "<6 && >1"則輸出結果:<6 && >1

[root@AliKvn shell]# sh -x if3.sh 
+ a=3
+ '[' 3 -gt 4 ']'
+ '[' 3 -gt 6 ']'
+ echo no
no      

邏輯判斷表達式:if [ $a -gt $b ]; if [ $a -lt 5 ]; if [ $b -eq 10 ]等 

大于小于等于等說明:-gt (>); -lt(<); -ge(>=); -le(<=);-eq(==); -ne(!=) 注意到處都是空格

大于小于等于也可以用這種方法表示,

[root@AliKvn shell]# a=3
[root@AliKvn shell]# if ((a>1)); then echo ok; fi
ok      

可以使用 && || 結合多個條件(&&并且,||或者)

if [ $a -gt 5 ] && [ $a -lt 10 ]; then
if [ $b -gt 5 ] || [ $b -lt 3 ]; then      

20.6 檔案目錄屬性判斷

[ -f file ]判斷是否是普通檔案,且存在

實驗

[root@AliKvn shell]# !vim 
vim file-f.sh  
#!/bin/bash
f="/tmp/shell-f.test"
if [ -f $f ]
then
        echo $f exist.
else
        touch $f
fi      

f="/tmp/shell-f.test" 變量f=/tmp/shell-f.test這個檔案,

if [ -f $f ]如果它是個檔案,

then則

        echo $f exist.輸出$f變量exist

else否則

        touch $f建立$f檔案

fi

2 執行腳本檢視進度

[root@AliKvn shell]# sh -x file-f.sh 
+ f=/tmp/shell-f.test
+ '[' -f /tmp/shell-f.test ']'
+ echo /tmp/shell-f.test exist.
/tmp/shell-f.test exist.      

[ -d file ] 判斷是否是目錄,且存在

[root@AliKvn shell]# vim file-d.sh 
#!/bin/bash
f="/tmp/shell-f.test"
if [ -d $f ]
then
        echo $f exist.
else
        touch $f
fi      

if [ -d $f ] -d判斷變量$f是否目錄

 touch $f 目錄和檔案都可以進行touch的。touch$f,如果存在,也不影響操作,隻影響time

[root@AliKvn shell]# sh -x file-d.sh 

+ f=/tmp/shell-f.test

+ '[' -d /tmp/shell-f.test ']'

+ touch /tmp/shell-f.test

[ -e file ] 判斷檔案或目錄是否存在,僅僅判斷是否存

1 編寫腳本,

[root@AliKvn shell]# !vim 
vim file-d.sh  
#!/bin/bash
f="/tmp/shell-f.test"
if [ -e $f ]
then
        echo $f exist.
else
        touch $f
fi      
[root@AliKvn shell]# sh -x !$
sh -x file-d.sh
+ f=/tmp/shell-f.test
+ '[' -e /tmp/shell-f.test ']'
+ echo /tmp/shell-f.test exist.
/tmp/shell-f.test exist.      

[ -r file ] 判斷檔案是否可讀

[root@AliKvn shell]# !vim
vim file-d.sh
#!/bin/bash
f="/tmp/shell-f.test"
if [ -r $f ]
then
        echo $f readable
else 
        echo $f unreadable
fi      

2 執行腳本

[root@AliKvn shell]# sh  file-d.sh 
/tmp/shell-f.test readable      

[ -w file ] 判斷檔案是否可寫

[root@AliKvn shell]# !vim
vim file-d.sh
#!/bin/bash
f="/tmp/shell-f.test"
if [ -r $f ]
then
        echo $f writeable
else 
        echo $f unwriteable
fi      
[root@AliKvn shell]# sh  file-d.sh 
/tmp/shell-f.test writeable      

[ -e file ] 判斷檔案或目錄是否存在

注意,執行判斷腳本的可讀可寫可執行狀态,隻針對目前使用者

#vim file-d.sh
#!/bin/bash
f="/tmp/shell-f.test"
if [ -r $f ]
then
        echo $f writeable
else 
        echo $f unwriteable
fi
[root@AliKvn shell]# !vim
vim file-d.sh
#!/bin/bash
f="/tmp/shell-f.test"
if [ -f $f ] 
then
        rm -f $f
fi
以上腳本,倒數4條的内容,等同于這條參數[ -f $f ] && rm -f $f 
&&表示前面的執行有效,後面才接着執行。
[ -f $f ] || touch $f 
||表示或者,前者指令是否定答案,才執行後者指令。      

以上都是用了如果存在的條件,

要表示如果檔案不存在,應該是[! -f $f] !表示非,取反,否定意義。

總結:

if 判斷檔案、目錄屬性

 [ -f file ]判斷是否是普通檔案,且存在

 [ -d file ] 判斷是否是目錄,且存在

 [ -e file ] 判斷檔案或目錄是否存在

 [ -r file ] 判斷檔案是否可讀

 [ -w file ] 判斷檔案是否可寫

 [ -x file ] 判斷檔案是否可執行

20.7 if特殊用法

if判斷的一些特殊用法

  • if [ -z  "$a" ]  這個表示當變量a的值為空時會怎麼樣。它與if [ -n "$a" ]是相對的,相反的。if [ -n "$a" ]=if [ ! -z "$a" ],他們是相同的。
  • if [-z  "$a" ] 這個表示當變量a的值為空時會怎麼樣。
  • if [ -n "$a" ] 這個表示當變量a的值不為空時,會怎樣。不為空,條件成立。
  • ! -z = -n 
  • ! -n = -z 他們的關系是相對的
  • 使用-z和-n判斷時,變量要用雙引号括起來,檔案和目錄就不需要。

1 編寫腳本,

[root@AliKvn shell]# vim shell20-7.sh
#!/bin/bash
n=`wc -l /tmp/lalal`        n的值為統計檔案的行數
if [ -z "$n" ]            如果n的值為空(或者檔案是不存在)
then                                        則
  echo error                        輸出error
                    exit然後退出
elif [ $n -gt 1000 ]        如果輸出結果大于1000
then則
        echo ljfiwo        輸出ljfiwo
fi      

2 執行腳本并輸出,略亂

[root@AliKvn shell]# sh -x shell20-7.sh 
++ wc -l /tmp/lalal
wc: /tmp/lalal: No such file or directory
+ n=
+ '[' -z '' ']'
+ echo error
error
+ exit      

3 這個腳本還可以更完美

[root@AliKvn shell]# !vim
vim file-f.sh 
#!/bin/bash
if [ ! -f /tmp/lalal ]                    判斷/tmp/lalal是否非檔案并判斷是否非存在,
then                                條件成立則
        echo "/tmp/lalal not exist."               輸出結果
        exit                        退出操作
fi

f="/tmp/shell-f.test"
if [ -f $f ]
then
        echo $f exist.
else
        touch $f
fi      

4 執行腳本

[root@AliKvn shell]# !vim
vim file-f.sh 
[root@AliKvn shell]# sh -x !$
sh -x file-f.sh
+ '[' '!' -f /tmp/lalal ']'
+ echo '/tmp/lalal not exist.'
/tmp/lalal not exist.
+ exit
[root@AliKvn shell]# sh  file-f.sh
/tmp/lalal not exist.      

if [ -n "$a" ] 表示當變量a的值不為空。可以判斷檔案,如果是字元串需要用雙引号引起,否則不用雙引号。

1 判斷檔案用法(不用雙引号标注)

判斷01.sh是否存在

[root@AliKvn shell]# ls

01.sh  file-d.sh  file-f.sh  if1.sh  if2.sh  if3.sh  shell20-7.sh

如果01.sh存在,那麼輸出yes

[root@AliKvn shell]# if [ -n 01.sh ]; then echo yes; fi

yes

2 判斷變量用法(需要雙引号标注)

[root@AliKvn ~]# echo $b
[root@AliKvn ~]# if [ -n "$b" ]; then echo $b; else echo "b is not here"; fi
b is not here      

指令的執行結果作為判斷條件

1 判斷系統中是否有mysql使用者存在

解決思路:mysql——》/etc/passwd——》grep ——》再執行條件判斷

操作:

[root@AliKvn ~]# if grep -wq 'mysql' /etc/passwd; then echo "exist"; fi
exist      

如果mysql1使用者不存在,判斷條件

[root@AliKvn ~]# if ! grep -wq 'mysql1' /etc/passwd; then echo "don't exist"; fi
don't exist      
[root@AliKvn ~]# if grep -wq 'mysql1' /etc/passwd; then echo "exist";else echo " don't exist "; fi
 don't exist      

以上兩種方法的性質是一樣的

同理

if [ ! -e file ]; then 表示檔案不存在時會怎麼樣

if (($a<1)); then …等同于 if [ $a -lt 1 ]; then...

[ ] 中不能使用<,>,==,!=,>=,<=這樣的符号(=是指派,==是等于)

20.8 case判斷

shell中的case判斷

在shell腳本中,除了用if來判斷邏輯外,還有一種常用的方式,case.

case腳本常用于偏寫系統服務的啟動腳本。例如/etc/init.d/network中就用到了case

case腳本格式:

case 變量名 in

value1)            值為value1的時候

command            執行什麼

;;                ;;表示一個判斷結束,進入到下一個判斷。

value2)            值為value2的時候

;;

*)                除此之外的值

command              又執行什麼

esac                case的倒寫,表示到此結束case腳本

在case程式中,可以在條件中使用|,表示或的意思, 比如

2|3)

   command

   ;;

腳本案例

目的:讓使用者輸入數值,然後用腳本判斷數值的範圍。

例如這個數字一個考試分數值,範圍是0-100,然後再在0-100裡面定義分數的級别:不合格,合格,優秀。

1 建立并編輯腳本

[root@AliKvn shell]# cd /root/shell/
[root@AliKvn shell]# vim sh-case-test.sh 
 #!/bin/bash
read -p "Please input a number: " n
if [ -z "$n" ]
then
    echo "Please input a number."
    exit 1
fi
n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
 echo "Please input a number."
 exit 1
fi
if [ $n -lt 60 ] && [ $n -ge 0 ]
then
    tag=1
elif [ $n -ge 60 ] && [ $n -lt 80 ]
then
    tag=2
elif [ $n -ge 80 ]  && [ $n -lt 90 ]
then
    tag=3
elif [ $n -ge 90 ] && [ $n -le 100 ]
then
    tag=4
else 
    tag=0
fi
case $tag in
    1)
echo "no pass"
        ;;
    2)
        echo "pass"
        ;;
    3)
        echo "good"
        ;;
    4)
        echo "very good"
        ;;
    *)
        echo "The number range is 0-100."
        ;; 
esac      

參數解釋:(解釋比較長)

#!/bin/bash
read -p "Please input a number: "  n
讓使用者輸入字元串,其實這算與使用者互動動作。
例如,read -p "xxx" n 
顯示的結果就是xxx:
那麼read -p "Please input a number: " n
輸出是Please input a number:
[root@AliKvn ~]# read -p "Please input a number: " n
Please input a number: 100
[root@AliKvn ~]# echo $n
100
if [ -z "$n" ]                    
如果n值為空,即使用者沒有輸入n值
then                          
則
    echo "Please input a number."          
輸出告知Please input a number.
    exit 1                        
退出,并傳回1個數值,這裡的用法跟echo $?的輸出一樣
fi
n1=`echo $n|sed 's/[0-9]//g'`                
判斷變量n1輸入的值是否純數字,是純數字的話,sed功能會将其解析置空(這裡的置空僅僅用于指令條件作用,并不是把n值置空),置空的話下面的條件不成立(if,if為一對)
if [ -n "$n1" ]                    
當n1數值不為空時(注意,這裡不是n值是n1,兩者性質不同),會被當作輸出不合法
then
 echo "Please input a number."            
繼續輸出Please input a number.
 exit 1                        
如果n1不為空的話,退出這條件,然後繼續判斷其他條件
fi
那就是說,當使用者輸入的字元串(n值)為純數字的話,條件成立(n1置空)。否則,使用者輸入的不是純數字的話,條件不成立,被腳本認為是不合法輸入,會繼續輸出Please input a number.
if [ $n -lt 60 ] && [ $n -ge 0 ]        條件能到這裡,表示n是一個純數字。當0<n<60
then                        則
    tag=1                    轉到标記1
elif [ $n -ge 60 ] && [ $n -lt 80 ]        當60<n<80
then則
    tag=2轉到标記2
elif [ $n -ge 80 ]  && [ $n -lt 90 ]        當80<n<90
then                        然後
    tag=3                    轉到标記3
elif [ $n -ge 90 ] && [ $n -le 100 ]        當90<n<=100
then                        然後
    tag=4                    轉到标記4
else                         否則
    tag=0                    轉到标記0
fi
case $tag in
    1)                    标記1(tag=1)
echo "no pass"                  輸出no pass
        ;;
    2)                      标記2
        echo "pass"            輸出pass
        ;;
    3)                    标記3
        echo "good"            輸出good
        ;;
    4)                    标記4
        echo "very good"           very good
        ;;
    *)                        以上4個标記都不符合的條件,這時候數值是等于0,又可能是大于100
        echo "The number range is 0-100."    輸出The number range is 0-100.提示使用者輸入正确的數值
        ;; 
esac                        結束腳本      

3 測試腳本

[root@AliKvn shell]# sh sh-case-test.sh 
Please input a number: 111
The number range is 0-100.      

超過定義的範圍100以外的數值,是以條件不成立,然後輸出了不成立的資訊,此處證明腳本的否定輸出是ok的。

3.1 檢視執行過程

[root@AliKvn shell]# sh -x sh-case-test.sh 
+ read -p 'Please input a number: ' n
Please input a number: 111
+ '[' -z 111 ']'
++ sed 's/[0-9]//g'
++ echo 111
+ n1=
+ '[' -n '' ']'
+ '[' 111 -lt 60 ']'
+ '[' 111 -ge 60 ']'
+ '[' 111 -lt 80 ']'
+ '[' 111 -ge 80 ']'
+ '[' 111 -lt 90 ']'
+ '[' 111 -ge 90 ']'
+ '[' 111 -le 100 ']'
+ tag=0
+ case $tag in
+ echo 'The number range is 0-100.'
The number range is 0-100.      

3.2 輸入不合法的數值數值,例如中英文。

[root@AliKvn shell]# sh  sh-case-test.sh 
Please input a number: ah1
Please input a number.      

執行過程 

[root@AliKvn shell]# sh -x sh-case-test.sh 
+ read -p 'Please input a number: ' n
Please input a number: ah1
+ '[' -z ah1 ']'
++ sed 's/[0-9]//g'
++ echo ah1
+ n1=ah
+ '[' -n ah ']'
+ echo 'Please input a number.'
Please input a number.
+ exit 1      

3.3 正确的範圍輸出結果(0-100)

[root@AliKvn shell]# sh  sh-case-test.sh 
Please input a number: 60
pass
[root@AliKvn shell]# sh  sh-case-test.sh 
Please input a number: 88  
good
[root@AliKvn shell]# sh  sh-case-test.sh 
Please input a number: 98
very good
[root@AliKvn shell]# sh  sh-case-test.sh 
Please input a number: 100
very good      
[root@AliKvn shell]# sh -x sh-case-test.sh 
+ read -p 'Please input a number: ' n
Please input a number: 60
+ '[' -z 60 ']'
++ sed 's/[0-9]//g'
++ echo 60
+ n1=
+ '[' -n '' ']'
+ '[' 60 -lt 60 ']'
+ '[' 60 -ge 60 ']'
+ '[' 60 -lt 80 ']'
+ tag=2
+ case $tag in
+ echo pass
pass
[root@AliKvn shell]# sh -x sh-case-test.sh 
+ read -p 'Please input a number: ' n
Please input a number: 88
+ '[' -z 88 ']'
++ sed 's/[0-9]//g'
++ echo 88
+ n1=
+ '[' -n '' ']'
+ '[' 88 -lt 60 ']'
+ '[' 88 -ge 60 ']'
+ '[' 88 -lt 80 ']'
+ '[' 88 -ge 80 ']'
+ '[' 88 -lt 90 ']'
+ tag=3
+ case $tag in
+ echo good
good
[root@AliKvn shell]# sh -x sh-case-test.sh 
+ read -p 'Please input a number: ' n
Please input a number: 98
+ '[' -z 98 ']'
++ sed 's/[0-9]//g'
++ echo 98
+ n1=
+ '[' -n '' ']'
+ '[' 98 -lt 60 ']'
+ '[' 98 -ge 60 ']'
+ '[' 98 -lt 80 ']'
+ '[' 98 -ge 80 ']'
+ '[' 98 -lt 90 ']'
+ '[' 98 -ge 90 ']'
+ '[' 98 -le 100 ']'
+ tag=4
+ case $tag in
+ echo 'very good'
very good
[root@AliKvn shell]# sh -x sh-case-test.sh 
+ read -p 'Please input a number: ' n
Please input a number: 100
+ '[' -z 100 ']'
++ sed 's/[0-9]//g'
++ echo 100
+ n1=
+ '[' -n '' ']'
+ '[' 100 -lt 60 ']'
+ '[' 100 -ge 60 ']'
+ '[' 100 -lt 80 ']'
+ '[' 100 -ge 80 ']'
+ '[' 100 -lt 90 ']'
+ '[' 100 -ge 90 ']'
+ '[' 100 -le 100 ']'
+ tag=4
+ case $tag in
+ echo 'very good'
very good