Linux-scripts-條件判斷

9.Scripts

本章同步視頻:https://edu.51cto.com/sd/e4874

9.3 善用判斷式

9.3.1 利用 test和[ ] 的測試功能

Shell test 命令的用法爲:

test expression

當 test 判斷 expression 成立時,退出狀態爲 0,否則爲非 0 值。

test 命令也可以簡寫爲[],它的用法爲:

[ expression ]

注意[]和expression之間的空格,這兩個空格是必須的,否則會導致語法錯誤。

test 和 [] 是等價的。

1.文件測試

測試的標誌

代表意義

1. 關於某個檔名的『文件類型』判斷,如 test -e filename 表示存在否

-e

該『檔名』是否存在?(常用)

-f

該『檔名』是否存在且爲檔案(file)(常用)

-d

該『文件名』是否存在且爲目錄(directory)(常用)

-b

該『檔名』是否存在且爲一個 block device 裝置?

-c

該『檔名』是否存在且爲一個 character device 裝置?

-S

該『檔名』是否存在且爲一個 Socket 檔案?

-p

該『檔名』是否存在且爲一個 FIFO (pipe) 檔案?

-L

該『檔名』是否存在且爲一個連結檔?

[root@localhost tmp]# ls

1.sh          file20200426  hello.sh     vmware-root

file20200425  file20200427  showname.sh

[root@localhost tmp]# test -e 1.sh       #判斷1.sh是否存在

[root@localhost tmp]# echo $?

0      #返回值爲0,表示上一條命令成立,即1.sh存在

[root@localhost tmp]# test -e 2.sh       #判斷2.sh是否存在

[root@localhost tmp]# echo $?

1      #返回值爲1,表示上一條命令不成立,即2.sh不存在

2.測試文件權限

測試的標誌

代表意義

2. 關於檔案的權限偵測,如 test -r filename 表示可讀否 (   root 權限常有例外)

-r

偵測該檔名是否存在且具有『可讀』的權限?

-w

偵測該檔名是否存在且具有『可寫』的權限?

-x

偵測該檔名是否存在且具有『可執行』的權限?

-u

偵測該文件名是否存在且具有『SUID』的屬性?

-g

偵測該文件名是否存在且具有『SGID』的屬性?

-k

偵測該文件名是否存在且具有『Sticky bit』的屬性?

-s

偵測該檔名是否存在且爲『非空白檔案』?

[root@localhost tmp]# ll 1.sh

-rw-r--r--. 1 root root 450 Apr 27 06:16 1.sh

[root@localhost tmp]# test -r 1.sh      #判斷1.sh是否可讀

[root@localhost tmp]# echo $?

0        #返回值爲0,表示1.sh可讀

[root@localhost tmp]# test -w 1.sh      #判斷1.sh是否可寫

[root@localhost tmp]# echo $?

0        #返回值爲0,表示1.sh可寫

[root@localhost tmp]# test -x 1.sh       #判斷1.sh是否可執行

[root@localhost tmp]# echo $?

1        #返回值爲1,表示1.sh不可執行

3.比較兩個文件

測試的標誌

代表意義

3. 兩個檔案之間的比較,如: test file1 -nt file2

-nt

(newer than)判斷 file1 是否比 file2

-ot

(older than)判斷 file1 是否比 file2

-ef

判斷 file1 file2 是否爲同一檔案,可用在判斷 hard link 的判定上。主要意義在判定,兩個檔案是否均指向同一個 inode 哩!

[root@localhost tmp]# test 1.sh -nt hello.sh

#判斷1.sh是不是比hello.sh新

[root@localhost tmp]# echo $?

0     #返回值爲0,表示1.sh比hello.sh新

4.數值比較

測試的標誌

代表意義

4. 關於兩個整數之間的判定,例如 test n1 -eq n2

-eq

兩數值相等 (equal)

-ne

兩數值不等 (not equal)

-gt

n1 大於 n2 (greater than)

-lt

n1 小於 n2 (less than)

-ge

n1 大於等於 n2 (greater than or equal)

-le

n1 小於等於 n2 (less than or equal)

[root@localhost tmp]# [ 5 -gt 9 ]     #判斷5>9

[root@localhost tmp]# echo $?

1     #返回值爲1,表示5>9不成立

5.判斷字符串

測試的標誌

代表意義

5. 判定字符串的數據

test -z string

判定字符串是否爲 0 ?若 string 爲空字符串,則爲 true

test -n string

判定字符串是否非爲 0 ?若 string 爲空字符串,則爲 false

注: -n 亦可省略

test str1 == str2

判定 str1 是否等於 str2 ,若相等,則回傳 true

test str1 != str2

判定 str1 是否不等於 str2 ,若相等,則回傳 false

[root@localhost tmp]# [ "abc" == "ABC" ]    #判斷“abc”是否等於“ABC”

[root@localhost tmp]# echo $?

1     #返回值爲1,表示不相等

6.多重條件判斷

測試的標誌

代表意義

6. 多重條件判定,例如: test -r filename -a -x filename

-a

(and)兩狀況同時成立!例如 test -r file -a -x file,則 file 同時具有 r x 權限時,纔回傳 true

-o

(or)兩狀況任何一個成立!例如 test -r file -o -x file,則 file 具有 r x 權限時,就可回傳 true

!

反相狀態,如 test ! -x file ,當 file 不具有 x 時,回傳 true

[root@localhost tmp]# [ 2 -lt 5 ] && [ 5 -lt 10 ]     #判斷2<5並且5<10

[root@localhost tmp]# echo $?

0

[root@localhost tmp]# [ 2 -lt 5 -a 5 -lt 10 ]          #返回值爲0,表示1.sh可讀

[root@localhost tmp]# echo $?

0

[root@localhost tmp]# ll 1.sh

-rw-r--r--. 1 root root 450 Apr 27 06:16 1.sh

[root@localhost tmp]# test -f 1.sh -a -r 1.sh     #判斷1.sh是普通文件,並且可讀

[root@localhost tmp]# echo $?

0

7.案例1

[root@localhost tmp]# vim 1.sh

#!/bin/bash

echo -e "Please input a filename, I will check the filename's type and permission. \n\n"

read -p "Input a filename : " filename

test -z ${filename} && echo "You MUST input a filename." && exit 0

##輸入檔名,並且判斷使用者是否真的有輸入字符串,如未輸入,則結束。

test ! -e ${filename} && echo "The filename '${filename}' DO NOT exist" && exit 0

# 判斷檔案是否存在,若不存在則顯示訊息並結束腳本。

test -f ${filename} && filetype="regulare file"        #是否是文件

test -d ${filename} && filetype="directory"        #是否是目錄

test -r ${filename} && perm="readable"       #是否可讀

test -w ${filename} && perm="${perm} writable"     #是否可寫

test -x ${filename} && perm="${perm} executable"     #是否可執行

echo "The filename: ${filename} is a ${filetype}"      #輸出文件類型

echo "And the permissions for you are : ${perm}"     #輸出文件權限

 

[root@localhost tmp]# ll hello.sh

-rw-r--r--. 1 root root 245 Apr 27 05:08 hello.sh

[root@localhost tmp]# chmod u+x 1.sh

[root@localhost tmp]# ./1.sh       #正常運行

Please input a filename, I will check the filename's type and permission.

Input a filename : hello.sh

The filename: hello.sh is a regulare file

And the permissions for you are : readable writable

[root@localhost tmp]# ./1.sh    #不輸入文件名

Please input a filename, I will check the filename's type and permission.

Input a filename :

You MUST input a filename.

[root@localhost tmp]# ./1.sh        #輸入錯誤的文件名

Please input a filename, I will check the filename's type and permission.

Input a filename : 2.sh

The filename '2.sh' DO NOT exist

8.案例2

[root@localhost tmp]# vim 1.sh

#!/bin/bash

#邏輯運算的兩種格式

read -p "Please input (Y/N): " yn

[ "${yn}" == "Y" -o "${yn}" == "y" ] && echo "OK, continue" && exit 0

#輸入Y或者y,輸出ok,退出

[ "${yn}" == "N" ] || [ "${yn}" == "n" ] && echo "Oh, interrupt!" && exit 0

#輸入N或者n,輸出oh,退出

echo "I don't know what your choice is" && exit 0

 

[root@localhost tmp]# ./1.sh     

Please input (Y/N): y    #輸入y

OK, continue

[root@localhost tmp]# ./1.sh

Please input (Y/N): n     #輸入n

Oh, interrupt!

9.3.2 [[ ]]

       [[ ]]是 Shell 內置關鍵字,它和 test 命令類似,也用來檢測某個條件是否成立。test 能做到的,[[ ]] 也能做到,而且 [[ ]] 做的更好;test 做不到的,[[ ]] 還能做到。可以認爲 [[ ]] 是 test 的升級版。[[ ]] 的用法爲:

[[ expression ]]

       當 [[ ]] 判斷 expression 成立時,退出狀態爲 0,否則爲非 0 值。注意[[ ]]和expression之間的空格,這兩個空格是必須的,否則會導致語法錯誤。

1.  [[ ]] 的優點

       [[ ]] 是 Shell 內置關鍵字,不是命令,在使用時沒有給函數傳遞參數的過程,所以 test 命令的某些注意事項在 [[ ]] 中就不存在了,具體包括:

u  不需要把變量名用雙引號""包圍起來,即使變量是空值,也不會出錯。

u  不需要、也不能對 >、< 進行轉義,轉義後會出錯。

2.[[ ]] 支持邏輯運算符

[root@localhost tmp]# [ -z "$str1" ] || [ -z "$str2" ]

[root@localhost tmp]# [ -z "$str1" -o -z "$str2" ]

[root@localhost tmp]# [[ -z $str1 || -z $str2 ]]

[root@localhost tmp]# [[ -z $str1 -o -z $str2 ]]

bash: syntax error in conditional expression

bash: syntax error near `-o'

#注:[[ ]] 剔除了 test 命令的-o和-a選項,你只能使用 || 和 &&。但可以寫成如下格式:

[root@localhost tmp]# [[ -z $str1 ]] || [[ -z $str2 ]]


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