新聞中心

創(chuàng)新互聯(lián)建站專注于靜寧企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),購物商城網(wǎng)站建設(shè)。靜寧網(wǎng)站建設(shè)公司,為靜寧等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站制作,專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)建站專業(yè)和態(tài)度為您提供的服務(wù)
test 命令有很多選項,可以進(jìn)行數(shù)值、字符串和文件三個方面的檢測。
Shell test 命令的用法為:
test expression
當(dāng) test 判斷 expression 成立時,退出狀態(tài)為 0,否則為非 0 值。
test 命令也可以簡寫為
[],它的用法為:
[ expression ]
注意
[]和
expression之間的空格,這兩個空格是必須的,否則會導(dǎo)致語法錯誤。
[]的寫法更加簡潔,比 test 使用頻率高。 在《Shell if else》中,我們使用 (()) 進(jìn)行數(shù)值比較,這節(jié)我們就來看一下如何使用 test 命令進(jìn)行數(shù)值比較。
#!/bin/bash
read age
if test $age -le 2; then
echo "嬰兒"
elif test $age -ge 3 && test $age -le 8; then
echo "幼兒"
elif [ $age -ge 9 ] && [ $age -le 17 ]; then
echo "少年"
elif [ $age -ge 18 ] && [ $age -le 25 ]; then
echo "成年"
elif test $age -ge 26 && test $age -le 40; then
echo "青年"
elif test $age -ge 41 && [ $age -le 60 ]; then
echo "中年"
else
echo "老年"
fi
其中,
-le選項表示小于等于,
-ge選項表示大于等于,
&&是邏輯與運(yùn)算符。
學(xué)習(xí) test 命令,重點(diǎn)是學(xué)習(xí)它的各種選項,下面我們就逐一講解。
1) 與文件檢測相關(guān)的 test 選項
| 文件類型判斷 | |
|---|---|
| 選 項 | 作 用 |
| -b filename | 判斷文件是否存在,并且是否為塊設(shè)備文件。 |
| -c filename | 判斷文件是否存在,并且是否為字符設(shè)備文件。 |
| -d filename | 判斷文件是否存在,并且是否為目錄文件。 |
| -e filename | 判斷文件是否存在。 |
| -f filename | 判斷文件是否存在,井且是否為普通文件。 |
| -L filename | 判斷文件是否存在,并且是否為符號鏈接文件。 |
| -p filename | 判斷文件是否存在,并且是否為管道文件。 |
| -s filename | 判斷文件是否存在,并且是否為非空。 |
| -S filename | 判斷該文件是否存在,并且是否為套接字文件。 |
| 文件權(quán)限判斷 | |
| 選 項 | 作 用 |
| -r filename | 判斷文件是否存在,并且是否擁有讀權(quán)限。 |
| -w filename | 判斷文件是否存在,并且是否擁有寫權(quán)限。 |
| -x filename | 判斷文件是否存在,并且是否擁有執(zhí)行權(quán)限。 |
| -u filename | 判斷文件是否存在,并且是否擁有 SUID 權(quán)限。 |
| -g filename | 判斷文件是否存在,并且是否擁有 SGID 權(quán)限。 |
| -k filename | 判斷該文件是否存在,并且是否擁有 SBIT 權(quán)限。 |
| 文件比較 | |
| 選 項 | 作 用 |
| filename1 -nt filename2 | 判斷 filename1 的修改時間是否比 filename2 的新。 |
| filename -ot filename2 | 判斷 filename1 的修改時間是否比 filename2 的舊。 |
| filename1 -ef filename2 | 判斷 filename1 是否和 filename2 的 inode 號一致,可以理解為兩個文件是否為同一個文件。這個判斷用于判斷硬鏈接是很好的方法 |
Shell test 文件檢測舉例:
#!/bin/bash
read filename
read url
if test -w $filename && test -n $url
then
echo $url > $filename
echo "寫入成功"
else
echo "寫入失敗"
fi
在 Shell 腳本文件所在的目錄新建一個文本文件并命名為 urls.txt,然后運(yùn)行 Shell 腳本,運(yùn)行結(jié)果為:
urls.txt↙
http://c.biancheng.net/shell/↙
寫入成功
2) 與數(shù)值比較相關(guān)的 test 選?項
| 選 項 | 作 用 |
|---|---|
| num1 -eq num2 | 判斷 num1 是否和 num2 相等。 |
| num1 -ne num2 | 判斷 num1 是否和 num2 不相等。 |
| num1 -gt num2 | 判斷 num1 是否大于 num2 。 |
| num1 -lt num2 | 判斷 num1 是否小于 num2。 |
| num1 -ge num2 | 判斷 num1 是否大于等于 num2。 |
| num1 -le num2 | 判斷 num1 是否小于等于 num2。 |
注意,test 只能用來比較整數(shù),小數(shù)相關(guān)的比較還得依賴 bc 命令。
Shell test 數(shù)值比較舉例:
#!/bin/bash
read a b
if test $a -eq $b
then
echo "兩個數(shù)相等"
else
echo "兩個數(shù)不相等"
fi
運(yùn)行結(jié)果1:
10 10
兩個數(shù)相等
運(yùn)行結(jié)果2:
10 20
兩個數(shù)不相等
3) 與字符串判斷相關(guān)的 test 選項
| 選 項 | 作 用 |
|---|---|
| -z str | 判斷字符串 str 是否為空。 |
| -n str | 判斷宇符串 str 是否為非空。 |
| str1 = str2 str1 == str2 |
=和==是等價的,都用來判斷 str1 是否和 str2 相等。 |
| str1 != str2 | 判斷 str1 是否和 str2 不相等。 |
| str1 \> str2 | 判斷 str1 是否大于 str2。\>是>的轉(zhuǎn)義字符,這樣寫是為了防止>被誤認(rèn)為成重定向運(yùn)算符。 |
| str1 \< str2 | 判斷 str1 是否小于 str2。同樣,\<也是轉(zhuǎn)義字符。 |
有C語言、C++、Python、Java 等編程經(jīng)驗(yàn)的讀者請注意,==、>、< 在大部分編程語言中都用來比較數(shù)字,而在 Shell 中,它們只能用來比較字符串,不能比較數(shù)字,這是非常奇葩的,大家要習(xí)慣。
其次,不管是比較數(shù)字還是字符串,Shell 都不支持 >= 和 <= 運(yùn)算符,切記。
Shell test 字符串比較舉例:
#!/bin/bash
read str1
read str2
#檢測字符串是否為空
if [ -z "$str1" ] || [ -z "$str2" ]
then
echo "字符串不能為空"
exit 0
fi
#比較字符串
if [ $str1 = $str2 ]
then
echo "兩個字符串相等"
else
echo "兩個字符串不相等"
fi
運(yùn)行結(jié)果:
http://c.biancheng.net/
http://c.biancheng.net/shell/
兩個字符串不相等
細(xì)心的讀者可能已經(jīng)注意到,變量 $str1 和 $str2 都被雙引號包圍起來,這樣做是為了防止 $str1 或者 $str2 是空字符串時出現(xiàn)錯誤,本文的后續(xù)部分將為你分析具體原因。
4) 與邏輯運(yùn)算相關(guān)的 test 選項
| 選 項 | 作 用 |
|---|---|
| expression1 -a expression | 邏輯與,表達(dá)式 expression1 和 expression2 都成立,最終的結(jié)果才是成立的。 |
| expression1 -o expression2 | 邏輯或,表達(dá)式 expression1 和 expression2 有一個成立,最終的結(jié)果就成立。 |
| !expression | 邏輯非,對 expression 進(jìn)行取反。 |
改寫上面的代碼,使用邏輯運(yùn)算選項:
#!/bin/bash
read str1
read str2
#檢測字符串是否為空
if [ -z "$str1" -o -z "$str2" ] #使用 -o 選項取代之前的 ||
then
echo "字符串不能為空"
exit 0
fi
#比較字符串
if [ $str1 = $str2 ]
then
echo "兩個字符串相等"
else
echo "兩個字符串不相等"
fi
前面的代碼我們使用兩個
[]命令,并使用
||運(yùn)算符將它們連接起來,這里我們改成
-o選項,只使用一個
[]命令就可以了。
在 test 中使用變量建議用雙引號包圍起來
test 和 [] 都是命令,一個命令本質(zhì)上對應(yīng)一個程序或者一個函數(shù)。即使是一個程序,它也有入口函數(shù),例如C語言程序的入口函數(shù)是 main(),運(yùn)行C語言程序就從 main() 函數(shù)開始,所以也可以將一個程序等效為一個函數(shù),這樣我們就不用再區(qū)分函數(shù)和程序了,直接將一個命令和一個函數(shù)對應(yīng)起來即可。
有了以上認(rèn)知,就很容易看透命令的本質(zhì)了:使用一個命令其實(shí)就是調(diào)用一個函數(shù),命令后面附帶的選項和參數(shù)最終都會作為實(shí)參傳遞給函數(shù)。
假設(shè) test 命令對應(yīng)的函數(shù)是 func(),使用
test -z $str1命令時,會先將變量 $str1 替換成字符串:
- 如果 $str1 是一個正常的字符串,比如 abc123,那么替換后的效果就是
test -z abc123,調(diào)用 func() 函數(shù)的形式就是func("-z abc123")。test 命令后面附帶的所有選項和參數(shù)會被看成一個整體,并作為實(shí)參傳遞進(jìn)函數(shù)。 - 如果 $str1 是一個空字符串,那么替換后的效果就是
test -z,調(diào)用 func() 函數(shù)的形式就是func("-z "),這就比較奇怪了,因?yàn)?code>-z選項沒有和參數(shù)成對出現(xiàn),func() 在分析時就會出錯。
如果我們給 $str1 變量加上雙引號,當(dāng) $str1 是空字符串時,
test -z "$str1"就會被替換為
test -z "",調(diào)用 func() 函數(shù)的形式就是
func("-z \"\""),很顯然,
-z選項后面跟的是一個空字符串(
\"表示轉(zhuǎn)義字符),這樣 func() 在分析時就不會出錯了。
所以,當(dāng)你在 test 命令中使用變量時,我強(qiáng)烈建議將變量用雙引號""包圍起來,這樣能避免變量為空值時導(dǎo)致的很多奇葩問題。
總結(jié)
test 命令比較奇葩,>、<、== 只能用來比較字符串,不能用來比較數(shù)字,比較數(shù)字需要使用 -eq、-gt 等選項;不管是比較字符串還是數(shù)字,test 都不支持 >= 和 <=。有經(jīng)驗(yàn)的程序員需要慢慢習(xí)慣 test 命令的這些奇葩用法。
對于整型數(shù)字的比較,我建議大家使用 (()),這在《Shell if else》中已經(jīng)進(jìn)行了演示。(()) 支持各種運(yùn)算符,寫法也符合數(shù)學(xué)規(guī)則,用起來更加方便,何樂而不為呢?
幾乎完全兼容 test ,并且比 test 更加強(qiáng)大,比 test 更加靈活的是
[[ ]];
[[ ]]不是命令,而是 Shell 關(guān)鍵字,下節(jié)《Shell [[]]》我們將會講解。
當(dāng)前名稱:Shelltest命令(Shell[])詳解,附帶所有選項及說明
轉(zhuǎn)載源于:http://fisionsoft.com.cn/article/ccspphh.html


咨詢
建站咨詢
