Shell test 命令
1. Shell test 命令概述
1.1 Shell test 命令簡(jiǎn)介
在我們之前章節(jié)學(xué)習(xí)了 Shell 的運(yùn)算符,其中大多數(shù)運(yùn)算都可以結(jié)合 test
命令來(lái)完成測(cè)試與比較操作,test
命令配合各種操作符號(hào),不僅可以完成測(cè)試邏輯表達(dá)式,還可以進(jìn)行文件,數(shù)字,字符串的比較。本文是一些常見(jiàn)用法的歸納總結(jié)。
1.2 為什么要用 test 命令
在 Shell 中每個(gè)命令都有其應(yīng)用場(chǎng)景,test 命令也不例外,其應(yīng)用場(chǎng)景幾乎遍布我們整個(gè) Shell 腳本的生命周期,基本上 Shell 腳本里面都會(huì)有其身影。
當(dāng)我們對(duì)數(shù)值進(jìn)行算術(shù)運(yùn)算,當(dāng)我們需要對(duì)文件進(jìn)行判斷,當(dāng)我們需要對(duì)邏輯或字符串進(jìn)行判斷的時(shí)候,這些情況都需要使用 test 命令來(lái)配合運(yùn)算符進(jìn)行操作。
2. Shell test 命令簡(jiǎn)介
2.1 狀態(tài)返回值
在我們學(xué)習(xí) test 命令之前,我們需要知道在 Linux 中執(zhí)行命令返回 0 為正常,返回非 0 表示異常,可以利用 $?
來(lái)獲取返回值。在下面的 test 操作中我們就會(huì)運(yùn)用此特性來(lái)進(jìn)行測(cè)試比較。
2.2 test 命令簡(jiǎn)介
- test 命令
test 為 Shell 內(nèi)置命令,其通常需要與 if 語(yǔ)句一塊使用。
- 語(yǔ)法格式
語(yǔ)法格式為 test expression
, 當(dāng) test 判斷 expression 為成立時(shí),返回狀態(tài)為 0,否則為非 0 值。
test 命令還可以簡(jiǎn)寫(xiě)為 [ ]
, 需要在兩邊中括號(hào)與 expression 是有一個(gè)空格,這個(gè)空格是必須的,否則會(huì)導(dǎo)致語(yǔ)法錯(cuò)誤。[]
的寫(xiě)法更加簡(jiǎn)潔,比 test 使用頻率更高。
我們可以簡(jiǎn)單來(lái)看示例:
[root@master shell_test]# cat test1.sh
#!/bin/bash
// 使用中括號(hào)
if test 10 -ne 1;then
echo "true"
else
echo "false"
fi
[root@master shell_test]# bash test1.sh
true
[root@master shell_test]# cat test2.sh
#!/bin/bash
// 使用test
if [ 10 -eq 1 ];then
echo "true"
else
echo "false"
fi
[root@master shell_test]# bash test2.sh
true
3. test 命令操作
test 命令操作主要配合比較運(yùn)算符進(jìn)行,可大體分為文件判斷 / 數(shù)組比較 / 字符串判斷 / 邏輯運(yùn)算等。
3.1 數(shù)值比較
數(shù)組比較其實(shí)就是 test 命令配合關(guān)系運(yùn)算符進(jìn)行數(shù)字比較。
比較符 | 描述 | 示例 |
---|---|---|
-eq,equal | 等于 | [1 -eq 1] 為 true |
-ne,not equal | 不等于 | [ 1 -ne 1] 為 false |
-gt,greater than | 大于 | [2 -gt 1] 為 true |
-lt,lesser than | 小于 | [2 -lt 1] 為 false |
-ge,greater or equal | 大于或等于 | [2 -ge 1] 為 true |
-le,lesser or equal | 小于或等于 | [2 -le 1] 為 false |
關(guān)系運(yùn)算顧名思義就是比較數(shù)字的大小,注意關(guān)系運(yùn)算符作用的對(duì)象為數(shù)字。
#!/bin/bash
num1=1
num2=2
echo "num1 為:${num1}"
echo "num2 為:${num2}"
if [ $num1 -eq $num2 ]
then
echo "$num1 -eq $num2 : num1 等于 num2"
else
echo "$num1 -eq $num2: num1 不等于 num2"
fi
if [ $num1 -ne $num2 ]
then
echo "$num1 -ne $num2: num1 不等于 num2"
else
echo "$num1 -ne $num2 : num1 等于 num2"
fi
if [ $num1 -gt $num2 ]
then
echo "$num1 -gt $num2: num1 大于 num2"
else
echo "$num1 -gt $num2: num1 不大于 num2"
fi
if [ $num1 -lt $num2 ]
then
echo "$num1 -lt $num2: num1 小于 num2"
else
echo "$num1 -lt $num2: num1 不小于 num2"
fi
if [ $num1 -ge $num2 ]
then
echo "$num1 -ge $num2: num1 大于或等于 num2"
else
echo "$num1 -ge $num2: num1 小于 num2"
fi
if [ $num1 -le $num2 ]
then
echo "$num1 -le $num2: num1 小于或等于 num2"
else
echo "$num1 -le $num2: num1 大于 num2"
fi
運(yùn)行結(jié)果為:
num1 為:1
num2 為:2
1 -eq 2: num1 不等于 num2
1 -ne 2: num1 不等于 num2
1 -gt 2: num1 不大于 num2
1 -lt 2: num1 小于 num2
1 -ge 2: num1 小于 num2
1 -le 2: num1 小于或等于 num
3.2 文件判斷
在本章節(jié)由于 test 命令與運(yùn)算符配合使用,與之前運(yùn)算符章節(jié)有重復(fù),我們?cè)诖藴毓手拢?test 命令來(lái)學(xué)習(xí)文件判斷。
文件測(cè)試在我們編寫(xiě) Shell 中與文件操作非常常用,熟練掌握文件操作可以在后續(xù)的 Shell 編寫(xiě)中得心應(yīng)手,例如 file 變量為:
操作符 | 說(shuō)明 | 舉例 |
---|---|---|
-d | file 檢測(cè)文件是否是目錄,如果是,則返回 true。 | [-d $file] 返回 false。 |
-f | file 檢測(cè)文件是否是普通文件(既不是目錄,也不是設(shè)備文件),如果是,則返回 true。 | [-f $file] 返回 true。 |
-c | file 檢測(cè)文件是否是字符設(shè)備文件,如果是,則返回 true。 | [-c $file] 返回 false。 |
-b | file 檢測(cè)文件是否是塊設(shè)備文件,如果是,則返回 true。 | [-b $file] 返回 false。 |
-g | file 檢測(cè)文件是否設(shè)置了 SGID 位,如果是,則返回 true。 | [-g $file] 返回 false。 |
-u | file 檢測(cè)文件是否設(shè)置了 SUID 位,如果是,則返回 true。 | [-u $file] 返回 false。 |
-k | file 檢測(cè)文件是否設(shè)置了粘著位 (Sticky Bit),如果是,則返回 true。 | [-k $file] 返回 false。 |
-p | file 檢測(cè)文件是否是有名管道,如果是,則返回 true。 | [-p $file] 返回 false。 |
-r | file 檢測(cè)文件是否可讀,如果是,則返回 true。 | [-r $file] 返回 true。 |
-w | file 檢測(cè)文件是否可寫(xiě),如果是,則返回 true。 | [-w $file] 返回 true。 |
-x | file 檢測(cè)文件是否可執(zhí)行,如果是,則返回 true。 | [-x $file] 返回 true。 |
-s | file 檢測(cè)文件是否為空(文件大小是否大于 0),不為空返回 true。 | [-s $file] 返回 true。 |
-e | file 檢測(cè)文件(包括目錄)是否存在,如果是,則返回 true。 | [-e $file] 返回 true。 |
例如:
#!/bin/bash
TEST_FILE="/etc/fstab"
echo "檢測(cè)的文件為:${TEST_FILE}"
echo "文件信息為:$(ls -l ${TEST_FILE})"
if [ -r $TEST_FILE ]
then
echo "文件可讀"
else
echo "文件不可讀"
fi
if [ -w $TEST_FILE ]
then
echo "文件可寫(xiě)"
else
echo "文件不可寫(xiě)"
fi
if [ -x $TEST_FILE ]
then
echo "文件可執(zhí)行"
else
echo "文件不可執(zhí)行"
fi
if [ -f $TEST_FILE ]
then
echo "文件為普通文件"
else
echo "文件為特殊文件"
fi
if [ -d $TEST_FILE ]
then
echo "文件是個(gè)目錄"
else
echo "文件不是個(gè)目錄"
fi
if [ -s $TEST_FILE ]
then
echo "文件不為空"
else
echo "文件為空"
fi
if [ -e $TEST_FILE ]
then
echo "文件存在"
else
echo "文件不存在"
fi
返回為:
檢測(cè)的文件為:/etc/fstab
文件信息為:-rw-r--r--. 1 root root 500 Jan 17 14:23 /etc/fstab
文件可讀
文件可寫(xiě)
文件不可執(zhí)行
文件為普通文件
文件不是個(gè)目錄
文件不為空
文件存在
3.3 字符串判斷
對(duì)于字符串判斷與數(shù)字對(duì)比,其作用的對(duì)象不同需要格外注意,利用 test 命令對(duì)于字符串進(jìn)行一些判斷操作,假定變量 a 為 “l(fā)inux”,變量 b 為 “shell”:
運(yùn)算符 | 說(shuō)明 | 舉例 |
---|---|---|
=/== | 檢測(cè)兩個(gè)字符串是否相等,其中 = 和 == 是相同的,相等返回 true。 | [$a = $b] 返回 false。 |
!= | 檢測(cè)兩個(gè)字符串是否相等,不相等返回 true。 | [$a != $b] 返回 true。 |
-z | 檢測(cè)字符串長(zhǎng)度是否為 0,為 0 返回 true。 | [-z $a] 返回 false。 |
-n | 檢測(cè)字符串長(zhǎng)度是否為 0,不為 0 返回 true。 | [-n “$a” ] 返回 true。 |
例如:
#!/bin/bash
str1="linux"
str2="shell"
echo "str1 為:${str1}"
echo "str2 為:${str2}"
if [ $str1 = $str2 ];then
echo "$str1 = $str2 : str1 等于 str2"
else
echo "$str1 = $str2: str1 不等于 str2"
fi
if [ $str1 != $str2 ];then
echo "$str1 != $str2 : str1 不等于 str2"
else
echo "$str1 != $str2: str1 等于 str2"
fi
if [ -z $str1 ];then
echo "-z $str1 : 字符串長(zhǎng)度為 0"
else
echo "-z $str1 : 字符串長(zhǎng)度不為 0"
fi
if [ -n "$str1" ];then
echo "-n $str1 : 字符串長(zhǎng)度不為 0"
else
echo "-n $str1 : 字符串長(zhǎng)度為 0"
fi
if [ ${str1} ];then
echo "str1 : 字符串不為空"
else
echo "str1 : 字符串為空"
fi
返回為:
str1 為:linux
str2 為:shell
linux = shell: str1 不等于 str2
linux != shell : str1 不等于 str2
-z linux : 字符串長(zhǎng)度不為 0
-n linux : 字符串長(zhǎng)度不為 0
str1 : 字符串不為空
3.4 邏輯運(yùn)算
利用 test 命令可以進(jìn)行邏輯判斷,以下介紹 Shell 的邏輯運(yùn)算符,假定變量 A 為 1,變量 b 為 2:
如果需要在一個(gè) test 中執(zhí)行多個(gè)判斷,需要使用 [[]]
, test 是 Shell 內(nèi)置關(guān)鍵字,不是命令,免除函數(shù)傳遞過(guò)程,因此更加建議使用 [[]]
。雙中括號(hào)有以下注意事項(xiàng):
- 不需要把變量名用雙引號(hào)
""
包圍起來(lái),即使變量是空值,也不會(huì)出錯(cuò); - 不需要、也不能對(duì) >、< 進(jìn)行轉(zhuǎn)義,轉(zhuǎn)義后會(huì)出錯(cuò);
- 其支持正則表達(dá)式,組合邏輯可以不使用 test 的 - a,-o 而使用 && ||。
與邏輯運(yùn)算符號(hào)對(duì)應(yīng)的 &&
可以使用 -a
,||
可以使用 -o
來(lái)替換。
運(yùn)算符 | 說(shuō)明 | 舉例 |
---|---|---|
&& | 邏輯的 AND | [[ $A -lt 10 && $B -gt 100 ]] 返回 false |
|| | 邏輯的 OR | [[ $A -lt 10 || $B -gt 100 ]] 返回 true |
例如:
#!/bin/bash
num1=1
num2=2
echo "num1 為:${num1}"
echo "num2 為:${num2}"
if [[ $num1 -lt 5 && $num2 -gt 5 ]];then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $num1 -lt 5 || $num2 -gt 5 ]];then
echo "返回 true"
else
echo "返回 false"
fi
if [ $num1 -lt 5 ] && [ $num2 -gt 5 ];then
echo "返回 true"
else
echo "返回 false"
fi
if [ $num1 -lt 5 ] || [ $num2 -gt 5 ];then
echo "返回 true"
else
echo "返回 false"
fi
if [ $num1 -lt 5 -a $num2 -gt 5 ];then
echo "返回 true"
else
echo "返回 false"
fi
if [ $num1 -lt 5 -o $num2 -gt 5 ];then
echo "返回 true"
else
echo "返回 false"
fi
返回:
num1 為:1
num2 為:2
返回 false
返回 true
返回 false
返回 true
返回 false
返回 true
4. 實(shí)例
4.1 需求
編寫(xiě)一個(gè)腳本,可以傳入任意多個(gè)數(shù)值,要求輸入的數(shù)字大于等于 0,腳本執(zhí)行輸出最小的和最大的數(shù)字。
4.2 思路
可以利用文件測(cè)試運(yùn)算符來(lái)判斷輸出的目錄是否正確,之后利用算術(shù)運(yùn)算符配合數(shù)組對(duì)文件或目錄進(jìn)行統(tǒng)計(jì)。
4.3 實(shí)現(xiàn)
#!/bin/bash
# Description: count file scripts
# Auth: kaliarch
# Email: kaliarch@163.com
# function: count file
# Date: 2020-03-21 14:00
# Version: 1.0
# 判斷輸入至少一個(gè)參數(shù)
[ $# -le 1 ] && echo "輸入?yún)?shù)錯(cuò)誤,至少輸入一個(gè)數(shù)字" && exit 1
for num in $*;
do
# 判斷輸入的都為數(shù)字且輸入數(shù)字大于等于0
[ "${num}" -ge 0 ] 2>/dev/null
[ $? -ne 0 ] && echo "輸入的${num}不符合參數(shù)規(guī)范" && exit 1
done
# 對(duì)目錄下的文件進(jìn)行統(tǒng)計(jì)
MIN_NUM=$1
MAX_NUM=$1
for num in $*;
do
if [ ${num} -gt ${MAX_NUM} ];then
MAX_NUM=${num}
elif [ ${num} -lt ${MIN_NUM} ];then
MIN_NUM=${num}
else
echo -e ""
fi
done
echo "輸入的參數(shù)總共為:$#"
echo "輸入的數(shù)字為:$*"
echo "其中最大的數(shù)字為:${MAX_NUM}"
echo "其中最小的數(shù)字為:${MIN_NUM}"
4.4 測(cè)試
當(dāng)我們不輸入任何參數(shù),或輸入單個(gè)參數(shù)的時(shí)候,提示輸入?yún)?shù)錯(cuò)誤,至少輸入一個(gè)數(shù)字;
如果輸入有包含字符串,則提示參數(shù)不規(guī)范;
當(dāng)輸入一些列數(shù)字的時(shí)候,可以得到正確的結(jié)果。
[root@master shell_test]# bash num_check.sh
輸入?yún)?shù)錯(cuò)誤,至少輸入一個(gè)數(shù)字
[root@master shell_test]# bash num_check.sh 1
輸入?yún)?shù)錯(cuò)誤,至少輸入一個(gè)數(shù)字
[root@master shell_test]# bash num_check.sh 1 "hell"
輸入的hell不符合參數(shù)規(guī)范
[root@master shell_test]# bash num_check.sh 12 13 32 435 0
輸入的參數(shù)總共為:5
輸入的數(shù)字為:12 13 32 435 0
其中最大的數(shù)字為:435
其中最小的數(shù)字為:
4. 注意事項(xiàng)
- 對(duì)于關(guān)系運(yùn)算,test 命令比較的對(duì)象為數(shù)字,不是字符串,一定要牢記這個(gè)注意點(diǎn);
- 對(duì)于字符串判斷,test 命令作用的為字符串,如果想比較數(shù)字,可以利用雙引號(hào)引起來(lái)通過(guò)字符串判斷。
5. 小結(jié)
在本章節(jié)由于 test 命令與運(yùn)算符配合使用,與之前運(yùn)算符章節(jié)有重復(fù),在此溫故知新,通過(guò)示例來(lái)更加熟悉 test 命令及相關(guān)運(yùn)算符,其是后期 Shell 腳本編寫(xiě)的流程框架,熟練掌握 test 命令的數(shù)值,文件,字符串與邏輯運(yùn)算,使得我們編寫(xiě) Shell 腳本更加得心應(yīng)手。