『忘了再學』Shell基礎 — 32、Shell中test測試命令詳解

2022-06-15 12:00:50

1、test測試命令

(1)test命令介紹

在Shell中的test測試命令,用於測試某種條件或某幾種條件是否真實存在。

在Shell中的test測試命令,是判斷語句和迴圈語句中條件測試的工具。test命令經常用於對判斷語句進行測試,用於檢查某個條件是否成立,它可以進行數值、字元和檔案三個方面的測試。

(2)test命令使用方式

Shell中test命令的用法有兩種:

  • 方式一:test expression
    test判斷expression成立時,返回值狀態為 0,否則為非 0 值。
    expression為表示式。
  • 方式二:test命令也可以簡寫為[ ]
    這時的test命令格式為:[ expression ]
    expression為表示式。
    注意:[]expression之間的空格,這兩個空格是必須的,否則會導致語法錯誤。[]的寫法更加簡潔,比 test使用頻率高。

(3)範例

需求:判斷一個檔案是否存在。

# 說明:
# -e 選項是test命令中判斷檔案是否存在的選項
# test命令用命令列的方式執行是沒有返回顯示的,
# 我們可以通過檢視$?變數的方式,檢視上一條命令是否正確執行。
# 返回值為0,表示上一條命令正確執行,
# 返回值為非0,表示上一條命令沒有正確執行。

# 判斷一個檔案是否存在
# 方式一:
[root@localhost tmp]# test -e student.txt
# 結果為0,表示上一條命令正確執行,說明student.txt檔案存在。
[root@localhost tmp]# echo $?
0

# 方式二:
[root@localhost tmp]# [ -e abc.txt ]
# 結果為非0,表示上一條命令沒有正確執行,說明abc.txt檔案不存在。
[root@localhost tmp]# echo $?
1

# 如果不想每次執行完test命令,還要檢視$?變數,來確定命令是否正確實行,
# 可以使用如下編寫方式:(方式一同理)
[root@localhost tmp]# [ -e abc.txt ] && echo yes || echo no
no
[root@localhost tmp]# [ -e student.txt ] && echo yes || echo no
yes

提示:在編寫Shell程式時,一般都是使用第二種書寫方式(沒見過不一般的情況)。

2、按照檔案型別進行判斷

我們先來看看test可以進行哪些檔案型別的判斷:

測試選項 作用
-b 檔案 判斷該檔案是否存在,並且是否為塊裝置檔案(是塊裝置檔案為真)。(少見)
-c 檔案 判斷該檔案是否存在,並且是否為字元裝置檔案(是字元裝置檔案為真)。(少見)
-d 檔案 判斷該檔案是否存在,並且是否為目錄檔案(是目錄為真)。(常見)
-e 檔案 判斷該檔案是否存在(存在為真)。(常見)
-f 檔案 判斷該檔案是否存在,並且是否為普通檔案(是普通檔案為真)。(常見)
-L 檔案 判斷該檔案是否存在,並且是否為符號連結檔案(是符號連結檔案為真)。(常見)
-p 檔案 判斷該檔案是否存在,並且是否為管道檔案(是管道檔案為真)。(少見)
-s 檔案 判斷該檔案是否存在,並且是否為非空(非空為真)。
-S 檔案 判斷該檔案是否存在,並且是否為通訊端檔案(是通訊端檔案為真)。

範例:

Linux系統中tmp目錄下的檔案,情況如下:

[root@localhost tmp]# ll
總用量 12
-rw-r--r--. 1 root root 371 10月 16 13:28 student.txt
-rw-r--r--. 1 root root 318 10月 14 18:03 test2.txt
-rw-r--r--. 1 root root  69 10月 16 17:39 test.txt

練習:

# 1.判斷student.txt檔案是否為目錄
[root@localhost tmp]# [ -d student.txt ] && echo yes || echo no
no

# 2.判斷student.txt檔案是否為普通檔案
[root@localhost tmp]# [ -f student.txt ] && echo yes || echo no
yes

# 3.判斷student.txt檔案是中內容是否為空
[root@localhost tmp]# [ -s student.txt ] && echo yes || echo no
yes

# 我們建立一個空檔案,在判斷一次。
[root@localhost tmp]# touch abc
[root@localhost tmp]# [ -s abc ] && echo yes || echo no
no


# 注意:
# 用命令列執行命令的時候可以寫相對路徑,因為我在對應的資料夾當中。
# 而在編寫Shell指令碼的時候,檔名一定要加上絕對路徑,要不然有可能找不到。

3、按照檔案許可權進行判斷

test命令是非常完善的判斷命令,還可以判斷檔案的許可權,我們通過下表來看看:

測試選項 作用
-r 檔案 判斷該檔案是否存在,並且是否該檔案擁有讀許可權(有讀許可權為真)(常用)
-w 檔案 判斷該檔案是否存在,並且是否該檔案擁有寫許可權(有寫許可權為真)(常用)
-x 檔案 判斷該檔案是否存在,並且是否該檔案擁有執行許可權(有執行許可權為真)(常用)
-u 檔案 判斷該檔案是否存在,並且是否該檔案擁有SUID許可權(有SUID許可權為真)(會用到)
-g 檔案 判斷該檔案是否存在,並且是否該檔案擁有SGID許可權(有SGID許可權為真)(會用到)
-k 檔案 判斷該檔案是否存在,並且是否該檔案擁有SBit許可權(有SBit許可權為真)

範例:

Linux系統中tmp目錄下的檔案,情況如下:

[root@localhost tmp]# ll
總用量 12
-rw-r--r--. 1 root root 371 10月 16 13:28 student.txt
-rw-r--r--. 1 root root 318 10月 14 18:03 test2.txt
-rw-r--r--. 1 root root  69 10月 16 17:39 test.txt

練習:

# 1.檢視tmp目錄student.txt是否有寫的許可權
# tmp目錄student.txt檔案許可權如下:
# -rw-r--r--. 1 root root 371 10月 16 13:28 student.txt
[root@localhost tmp]# [ -w student.txt ] && echo yes || echo no
yes
# 上面證明在tmp目錄中student.txt檔案存在,並擁有寫許可權。

# 注意:
# -w選項是分不清是所有者,所陣列,和其他人誰有寫許可權的,
# 只要該檔案任何一個身份中出現寫的許可權,-w選項的判斷就是正確的。
# 如果你非要判斷某一個身份是否有寫的許可權,
# 就需要我們自己手動把檔案的許可權按需求擷取下來,然後編寫程式來判斷。

# -r選項和-x選項同理。



# 2.判斷student.txt檔案是否擁有SUID許可權
[root@localhost tmp]# [ -u student.txt ] && echo yes || echo no
no

# 可以看到student.txt檔案沒有設定SUID許可權
# 我們接下來給student.txt檔案設定一下SUID許可權

[root@localhost tmp]# chmod u+s student.txt

# 檢視一下測試student.txt檔案的許可權
[root@localhost tmp]# ll student.txt
-rwSr--r--. 1 root root 371 10月 16 13:28 student.txt

# 可以看到student.txt檔案的許可權中多了一個大S許可權
# 關於SUID許可權相關內容可以點選如下連結進行檢視:
# https://blog.csdn.net/Liuyuelinjiayou/article/details/107197846
# 接下來我們在判斷student.txt檔案受否擁有SUID許可權
[root@localhost tmp]# [ -u student.txt ] && echo yes || echo no
yes

# 練習完成後,儘量儘快的還原檔案,一般之後的練習使用。
[root@localhost tmp]# chmod u-s student.txt
[root@localhost tmp]# ll student.txt
-rw-r--r--. 1 root root 371 10月 16 13:28 student.txt

4、兩個檔案之間進行比較

通過下表來看看如何進行兩個檔案之間的比較(少用瞭解一下):

測試選項 作用
檔案1 -nt 檔案2 判斷檔案1的修改時間是否比檔案2的新(如果新則為真)。
檔案1 -ot 檔案2 判斷檔案1的修改時間是否比檔案2的舊(如果舊則為真)。
檔案1 -ef 檔案2 判斷檔案1是否和檔案2的Inode號一致,可以理解為兩個檔案是否為同一個檔案。這個用於判斷硬連結是很好的方法。

範例:

# 把tmp目錄下的student.txt檔案,硬連線到root目錄下student檔案。
# 也就是給tmp目錄下的student.txt檔案建立一個硬連線,在root目錄下。
[root@localhost tmp]# ln /tmp/student.txt  /root/student

# 然後判斷/tmp/student.txt檔案和/root/student檔案是否為同一檔案。
[root@localhost tmp]# [ /tmp/student.txt -ef /root/student ] && echo yes || echo no
yes
# 結果為是。

5、兩個整數之間比較

通過下表來學習下如何在兩個整數之間進行比較(常用):

測試選項 作用
整數1 -eq 整數2 判斷整數1是否和整數2相等(相等為真)
整數1 -ne 整數2 判斷整數1是否和整數2不相等(不相等為真)
整數1 -gt 整數2 判斷整數1是否大於整數2(大於為真)
整數1 -lt 整數2 判斷整數1是否小於整數2(小於為真)
整數1 -ge 整數2 判斷整數1是否大於等於整數2(大於等於為真)
整數1 -le 整數2 判斷整數1是否小於等於整數2(小於等於為真)

範例:

# 1.-eq等於
[root@localhost tmp]# [ 66 -eq 88 ] && echo yes || echo no
no

# 2.-lt小於
[root@localhost tmp]# [ 66 -lt 88 ] && echo yes || echo no
yes

# 3.-le小於等於
[root@localhost tmp]# [ 66 -le 88 ] && echo yes || echo no
yes

# 在Shell程式設計的時候,會把數值型變數引入條件判斷表示式中,
# 就不會是光突突的數位了。

6、字串的判斷

通過下表我們來學習下字串的判斷(常用):

測試選項 作用
-z 字串 判斷字串是否為空(為空返回真)
-n 字串 判斷字串是否為非空(非空返回真)
字串1 == 字串2 判斷字串1是否和字串2相等(相等返回真)
字串1 != 字串2 判斷字串1是否和字串2不相等(不相等返回真)

範例1:

# 判斷變數name是否為空
[root@localhost tmp]# [ -z "$name" ] && echo yes || echo no
yes

# 給變數name賦值
[root@localhost tmp]# name=Zhubj
# 因為不為空,所以返回no
[root@localhost tmp]# [ -z "$name" ] && echo yes || echo no
no

範例2:

# 給變數aa和變數bb賦值
[root@localhost tmp]# aa=Shell
[root@localhost tmp]# bb=Shell

# 判斷變數aa和變數bb是否相等
# 因為變數aa的值為"Shell",不等於字串"bb",所以返回no。
[root@localhost tmp]# [ "$aa" == "bb" ] && echo yes || echo no
no

# 變數aa和變數bb的值都為"Shell",所以返回yes。
[root@localhost tmp]# [ "$aa" == "$bb" ] && echo yes || echo no
yes

提示:Shell中用==雙等號來比對兩個字串是否相等(內容相同)。使用-eq來比對兩個整數是否相等。

7、多重條件判斷

通過下表來看看多重條件判斷是什麼樣子的(常用):

測試選項 作用
判斷1 -a 判斷2 邏輯與,判斷1和判斷2都成立,最終的結果才為真。
判斷1 -o 判斷2 邏輯或,判斷1和判斷2有一個成立,最終的結果就為真。
! 判斷 邏輯非,使原始的判斷式取反。

也就是說多重條件判斷就是,可以同時判斷多個條件,前邊的條件都可以。

範例1:

# 定義一個變數aa賦值並賦值66。
[root@localhost tmp]# aa=66

# 判斷變數aa是否有值,同時判斷變數aa的是否大於88。
# 因為變數aa的值不大於88,所以雖然第一個判斷值為真,返回的結果也是假。
[root@localhost tmp]# [ -n "$aa" -a "$aa" -gt 88 ] && echo "yes" || echo "no"
no


# 給變數aa重新賦個大於88的值,返回結果就是yes了。
[root@localhost tmp]# aa=99
[root@localhost tmp]# [ -n "$aa" -a "$aa" -gt 88 ] && echo "yes" || echo "no"
yes

範例2:

# 練習邏輯非
# 說明:
# "-n"選項是變數aa不為空,返回值就是真。
# 加入"!"之後,判斷值就會取反,所以當變數aa有值時,返回值是假.
# "!"+"-n"選項就和"-z"選項作用一樣了。
[root@localhost tmp]# aa=99
[root@localhost tmp]# [ ! -n "$aa" ] && echo "yes" || echo "no"
no

# 在定義一個沒有賦值的變數cc,返回結果就是yes。
[root@localhost tmp]# [ ! -n "$cc" ] && echo "yes" || echo "no"
yes


# 注意:"!"和"-n"選項之間必須加入空格,否則會報錯的。