十六週三次課

20.5 shell腳本中的邏輯判斷

格式1:if 條件 ; then 語句; fi

[root@test220 ~]# a=5

[root@test220 ~]# if [ $a -gt 3 ]

> then

> echo ok

> fi

ok

[root@test220 ~]# if [ $a -gt 3 ]; then echo ok; fi

ok

改成shell腳本

[root@test220 script]# vim if1.sh

#!/bin/bash

a=5

[ $a -gt 3 ]

then

echo ok

fi

調試;

[root@aiker02 script]# sh -x !$

sh -x if1.sh

+ a=5

+ '[' 5 -gt 3 ']'

+ echo ok

ok

[root@test220 ~]# for i in `seq 1 5`;do echo $i;done;

1

2

3

4

5

[root@test220 ~]# for i in `seq 1 5`

> do echo $i

> done

1

2

3

4

5

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

[root@test220 script]# vim if2.sh

#!/bin/bash

a=3

if [ $a -gt 3 ]

then

echo ok

else

echo nook!

fi

[root@aiker02 script]# sh -x !$

sh -x if2.sh

+ a=3

+ '[' 3 -gt 3 ']'

+ echo 'nook!'

nook!

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

[root@aiker02 script]# vim if3.sh

#!/bin/bash

a=3

if [ $a -gt 4 ]

then

echo ">4"

elif [ $a -lt 6 ]

then

echo " <6 && >1"

else

echo nook!

fi

[root@aiker02 script]# sh -x !$

sh -x if3.sh

+ a=3

+ '[' 3 -gt 4 ']'

+ '[' 3 -lt 6 ']'

+ echo ' <6 && >1'

<6 && >1

邏輯判斷表達式:
if [ $a -gt $b ]; if [ $a -lt 5 ]; if [ $b -eq 10 ]等
-gt(>); -lt(<); -ge(>=); -le(<=);-eq(==); -ne(!=) 注意到處都是空格

參數 說明
-eq 等於則爲真
-ne 不等於則爲真
-gt 大於則爲真
-ge 大於等於則爲真
-lt 小於則爲真
-le 小於等於則爲真
[root@aiker02 script]# a=3
[root@aiker02 script]# 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@aiker02 script]# vim test1.sh

#!/bin/bash

f='/tmp/aiker'

if [ -f $f ]

then

echo $f exist

else

touch $f

fi

[root@aiker02 script]# sh -x test1.sh

+ f=/tmp/aiker

+ '[' -f /tmp/aiker ']'

+ touch /tmp/aiker

[root@aiker02 script]# sh -x test1.sh

+ f=/tmp/aiker

+ '[' -f /tmp/aiker ']'

+ echo /tmp/aiker exist

/tmp/aiker exist

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

[root@aiker02 script]# vim testd.sh

#!/bin/bash

f='/tmp/aiker'

if [ -d $f ]

then

echo $f exist

else

touch $f

fi

[root@aiker02 script]# sh -x !$

sh -x testd.sh

+ f=/tmp/aiker

+ '[' -d /tmp/aiker ']'

+ touch /tmp/aiker

[ -e file ] 判斷文件或目錄是否存在

#!/bin/bash

f='/tmp/aiker'

if [ -e $f ]

then

echo $f exist

else

touch $f

fi

[root@aiker02 script]# sh -x !$

sh -x teste.sh

+ f=/tmp/aiker

+ '[' -e /tmp/aiker ']'

+ echo /tmp/aiker exist

/tmp/aiker exist

[ -r file ] 判斷文件是否可讀

[root@aiker02 script]# vim testr.sh

#!/bin/bash

f='/tmp/aiker'

if [ -r $f ]

then

echo $f is readable

else

echo $f is unreadable

fi

[root@aiker02 script]# sh -x !$

sh -x testr.sh

+ f=/tmp/aiker

+ '[' -r /tmp/aiker ']'

+ echo /tmp/aiker is readable

/tmp/aiker is readable

[ -w file ] 判斷文件是否可寫

[root@aiker02 script]# vim testw.sh

#!/bin/bash

f='/tmp/aiker'

if [ -w $f ]

then

echo $f is writeable

else

echo $f is not writeable

fi

[root@aiker02 script]# sh -x !$

sh -x testw.sh

+ f=/tmp/aiker

+ '[' -w /tmp/aiker ']'

+ echo /tmp/aiker is writeable

/tmp/aiker is writeable

[ -x file ] 判斷文件是否可執行

[root@aiker02 script]# vim testx.sh

#!/bin/bash

f='/tmp/aiker'

if [ -x $f ]

then

echo $f is exe file

else

echo $f is not exe file

fi

[root@aiker02 script]# sh -x !$

sh -x testx.sh

+ f=/tmp/aiker

+ '[' -x /tmp/aiker ']'

+ echo /tmp/aiker is not exe file

/tmp/aiker is not exe file

[root@aiker02 script]# cat !$

cat testf2.sh

#!/bin/bash

f='/tmp/aiker'

[ -f $f ] && rm -f $f ##前面的執行成功就執行後面的

[ -f $f ] || touch $f ##前面的不成功才執行後面的

if [ -f $f ]

then

rm -f $f

else

touch $f

fi
if [ ! -f $f ] ##!是取非,!f不存在

then

touch $f

fi
[root@aiker02 script]# sh -x !$

sh -x testf2.sh

+ f=/tmp/aiker

+ '[' -f /tmp/aiker ']'

+ rm -f /tmp/aiker

+ '[' -f /tmp/aiker ']'

+ touch /tmp/aiker

+ '[' -f /tmp/aiker ']'

+ rm -f /tmp/aiker

+ '[' '!' -f /tmp/aiker ']'

+ touch /tmp/aiker

<table>
<tbody>
<tr>
<td width="100">測試的標誌</font></td><td>代表意義</font></td>
</tr>
<tr>
<td colspan="2">1. 關於某個檔名的『文件類型』判斷,如 test -e filename 表示存在否</font></td>
</tr>
<tr>
<td>-e</td><td>該『檔名』是否存在?(常用)</td>
</tr>
<tr>
<td>-f</td><td>該『檔名』是否存在且爲文件(file)?(常用)</td>
</tr>
<tr>
<td>-d</td><td>該『檔名』是否存在且爲目錄(directory)?(常用)</td>
</tr>
<tr>
<td>-b</td><td>該『檔名』是否存在且爲一個 block device 裝置?</td>
</tr>
<tr>
<td>-c</td><td>該『檔名』是否存在且爲一個 character device 裝置?</td>
</tr>
<tr>
<td>-S</td><td>該『檔名』是否存在且爲一個 Socket 文件?</td>
</tr>
<tr>
<td>-p</td><td>該『檔名』是否存在且爲一個 FIFO (pipe) 文件?</td>
</tr>
<tr>
<td>-L</td><td>該『檔名』是否存在且爲一個連結檔?</td>
</tr>
<tr>
<td colspan="2">2. 關於文件的權限偵測,如 test -r filename 表示可讀否 (但 root 權限常有例外)</font></td>
</tr>
<tr>
<td>-r</td><td>偵測該檔名是否存在且具有『可讀』的權限?</td>
</tr>
<tr>
<td>-w</td><td>偵測該檔名是否存在且具有『可寫』的權限?</td>
</tr>
<tr>
<td>-x</td><td>偵測該檔名是否存在且具有『可運行』的權限?</td>
</tr>
<tr>
<td>-u</td><td>偵測該檔名是否存在且具有『SUID』的屬性?</td>
</tr>
<tr>
<td>-g</td><td>偵測該檔名是否存在且具有『SGID』的屬性?</td>
</tr>
<tr>
<td>-k</td><td>偵測該檔名是否存在且具有『Sticky bit』的屬性?</td>
</tr>
<tr>
<td>-s</td><td>偵測該檔名是否存在且爲『非空白文件』?</td>
</tr>
<tr>
<td colspan="2">3. 兩個文件之間的比較,如: test file1 -nt file2</font></td>
</tr>
<tr>
<td>-nt</td><td>(newer than)判斷 file1 是否比 file2 新</td>
</tr>
<tr>
<td>-ot</td><td>(older than)判斷 file1 是否比 file2 舊</td>
</tr>
<tr>
<td>-ef</td><td>判斷 file1 與 file2 是否爲同一文件,可用在判斷 hard link 的判定上。
主要意義在判定,兩個文件是否均指向同一個 inode 哩!</td>
</tr>
<tr>
<td colspan="2">4. 關於兩個整數之間的判定,例如 test n1 -eq n2</font></td>
</tr>
<tr>
<td>-eq</td><td>兩數值相等 (equal)</td>
</tr>
<tr>
<td>-ne</td><td>兩數值不等 (not equal)</td>
</tr>
<tr>
<td>-gt</td><td>n1 大於 n2 (greater than)</td>
</tr>
<tr>
<td>-lt</td><td>n1 小於 n2 (less than)</td>
</tr>
<tr>
<td>-ge</td><td>n1 大於等於 n2 (greater than or equal)</td>
</tr>
<tr>
<td>-le</td><td>n1 小於等於 n2 (less than or equal)</td>
</tr>
<tr>
<td colspan="2">5. 判定字串的數據</font></td>
</tr>
<tr>
<td>test -z string</td><td>判定字串是否爲 0 ?若 string 爲空字串,則爲 true</td>
</tr>
<tr>
<td>test -n string</td><td>判定字串是否非爲 0 ?若 string 爲空字串,則爲 false。<br>注: -n 亦可省略</td>
</tr>
<tr>
<td>test str1 = str2</td><td>判定 str1 是否等於 str2 ,若相等,則回傳 true</td>
</tr>
<tr>
<td>test str1 != str2</td><td>判定 str1 是否不等於 str2 ,若相等,則回傳 false</td>
</tr>
<tr>
<td colspan="2">6. 多重條件判定,例如: test -r filename -a -x filename</font></td>
</tr>
<tr>
<td>-a</td><td>(and)兩狀況同時成立!例如 test -r file -a -x file,則 file 同時具有 r 與
x 權限時,纔回傳 true。</td>
</tr>
<tr>
<td>-o</td><td>(or)兩狀況任何一個成立!例如 test -r file -o -x file,則 file 具有 r 或
x 權限時,就可回傳 true。</td>
</tr>
<tr>
<td>!</td><td>反相狀態,如 test ! -x file ,當 file 不具有 x 時,回傳 true</td>
</tr>
</tbody>
</table>

if-then語句,格式如下:

if command_1

then command_2

command_3

fi command_4

在if-then語句中使用了命令返回碼$?,即當command_1執行成功時才執行command_2和 command_3,而command_4總是執行 ,例:

在備份成功時刪除原始文件:

if  l s  - a |  cpi o - o > / dev/ rm t / 0h

then

rm  - rf  *

fi

測試條件之否定,使用!

測試條件之邏輯運算

-a And

-o Or

例:

test -r empty -a -s empty

進行test測試的標準方法

因爲test命令在 shell編程中佔有很重要的地位,爲了使shell能 同其他編程語言一樣 便於閱讀和組織, Bourne Shell在使用test 測試時使用了另一種方法:用方括號將整個 test測試括起來:

例:

int1=4

[ $int1 -gt 2 ]

echo $?

0

20.7 if特殊用法

if [ -z "$a" ] 這個表示當變量a的值爲空時會怎麼樣

[root@aiker02 ~]# vim !$

vim testz0.sh

#!/bin/bash

n=`wc -l /tmp/aikerv | awk '{print $1}'`

if [ -z "$n" ]

then

echo error

exit 1

else

if [ $n -gt 100 ]

then

echo $n over 100 hang.

fi

fi

[root@aiker02 ~]# sh -x testz0.sh

++ awk '{print $1}'

++ wc -l /tmp/aikerv

+ n=1

+ '[' -z 1 ']'

+ '[' 1 -gt 100 ']'

或者

[root@aiker02 ~]# vim testz.sh

#!/bin/bash

n=`wc -l /tmp/aikerv | awk '{print $1}'`

if [ -z "$n" ]

then

echo error

exit 1

elif [ $n -gt 100 ]

then

echo $n over 100 hang.

fi

[root@aiker02 ~]# sh -x testz.sh

++ awk '{print $1}'

++ wc -l /tmp/aikerv

+ n=1

+ '[' -z 1 ']'

+ '[' 1 -gt 100 ']'

if [ -n "$a" ] 表示當變量a的值不爲空

[root@aiker02 ~]# if [ -n autosshd ]; then echo OK; fi #判斷文件內容不爲空,如果爲文件,不用雙引號引起

OK

[root@aiker02 ~]# if [ -n "$b" ]; then echo $b; else echo "b is null"; fi ##如果使用變量,一定要“”

b is null

if grep -q '123' 1.txt; then 表示如果1.txt中含有'123'的行時會怎麼樣

[root@aiker02 ~]# grep -w 'operator' /etc/passwd #-w精確過濾

operator:x:11:0:operator:/root:/sbin/nologin

[root@aiker02 ~]# if grep -w 'operator' /etc/passwd; then echo "operator is exist."; fi ##grep輸出了結果

operator:x:11:0:operator:/root:/sbin/nologin

operator is exist.

[root@aiker02 ~]# if grep -wq 'operator' /etc/passwd; then echo "operator is exist."; fi ##-q不輸出過程

operator is exist.

if ! grep -wq 'operator' /etc/passwd; then echo "operator is not exist" &&  useradd operator; fi ##不存在operator

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

[root@aiker02 script]# vim testne.sh ##!取反

#!/bin/bash

f='/tmp/aiker'

if [ ! -e $f ]

then

echo $f is not exist

touch $f

else

echo $f is exist

fi

[root@aiker02 script]# sh -x testne.sh

+ f=/tmp/aiker

+ '[' '!' -e /tmp/aiker ']'

+ echo /tmp/aiker is exist

/tmp/aiker is exist

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

[root@aiker02 script]# vim testlt.sh

#!/bin/bash

a=6

if (($a<5))

then

echo $a 'is < 5'

elif [ $a -lt 10 ]

then

b=$(($a+1))

echo $b

fi

[root@aiker02 script]# sh -x testlt.sh

+ a=6

+ (( 6<5 ))

+ '[' 6 -lt 10 ']'

+ b=7

+ echo 7

7

[ ] 中不能使用<,>,==,!=,>=,<=這樣的符號,(())可以使用,[[]]可以使用,可以用[[]]代替[]

if嵌套及elif結構

    if command 
    then command 
    else
        if command 
              then command 
          else
           if command 
             then command 
           fi 
        fi 
    fi  

改進:使用elif結構

                 if command 
                      then command 
                 elif command 
                     then command 
                 elif command 
                     then command 
                 fi         

20.8/20.9 case判斷

格式

case 變量名 in  
value1)  
command  
;;  
value2)  
command  
;;  
*)  
commond  
;;  
esac

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

2|3)
command
;;

shell腳本案例

#!/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" ] ##判斷是否爲空,如果不爲空就提示輸入數字,注意-n 變量需要“”

then

echo "Please input a number."

exit 1

fi

if [ $n -lt 60 ] && [ $n -ge 0 ]

then

tag=1 ##tag打標記

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 "is bad"

;;

2)

echo "ok"

;;

3)

echo "good"

;;

4)

echo "very good"

;;

*)

echo "The number range is 0-100."

;;

esac
[root@aiker02 script]# cat !$

cat case0.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 "is bad"

;;

2)

echo "ok"

;;

3)

echo "good"

;;

4)

echo "very good"

;;

*)

echo "The number range is 0-100."

;;

esac
[root@aiker02 script]# sh -x !$

sh -x case0.sh

+ read -p 'Please input a number: ' n

Please input a number: 49

+ '[' -z 49 ']'

++ sed 's/[0-9]//g'

++ echo 49

+ n1=

+ '[' -n '' ']'

+ '[' 49 -lt 60 ']'

+ '[' 49 -ge 0 ']'

+ tag=1

+ case $tag in

+ echo 'is bad'

is bad

[root@aiker02 script]# sh -x case0.sh

+ read -p 'Please input a number: ' n

Please input a number: 6+^H0

+ '[' -z $'6+\b0' ']'

++ sed 's/[0-9]//g'

++ echo $'6+\b0'

+ n1=$'+\b'

+ '[' -n $'+\b' ']'

+ echo 'Please input a number.'

Please input a number.

+ exit 1
[root@aiker02 script]# sh -x case0.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 ok

ok
[root@aiker02 script]# sh -x case0.sh

+ read -p 'Please input a number: ' n

Please input a number: 500

+ '[' -z 500 ']'

++ sed 's/[0-9]//g'

++ echo 500

+ n1=

+ '[' -n '' ']'

+ '[' 500 -lt 60 ']'

+ '[' 500 -ge 60 ']'

+ '[' 500 -lt 80 ']'

+ '[' 500 -ge 80 ']'

+ '[' 500 -lt 90 ']'

+ '[' 500 -ge 90 ']'

+ '[' 500 -le 100 ']'

+ tag=0

+ case $tag in

+ echo 'The number range is 0-100.'

The number range is 0-100.

case結構 :

case value in

pattern1)

command

command;;

pattern2)

command

command;;

...

patternn)

command

esac

case語句只執行第一個匹配模式,

例:

case "$CHOICE" in

1|R) echo "Restore";;

2|B) echo "Backup";;

3|U) echo "Unload";;

*) echo "Sorry $CHOICE is not a valid choice

exit 1

esac
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章