10 shell 條件測試

2021-09-26 21:27:35 字數 4732 閱讀 6353

命令test[可以測試乙個條件是否成立,如果測試結果為真,則該命令的exit status為0,如果測試結果為假,則命令的exit status為1(注意與c語言的邏輯表示正好相反)。例如測試兩個數的大小關係:

itcast@ubuntu:~$ var=2

itcast@ubuntu:~$ test

$var -gt 1

itcast@ubuntu:~$ echo$?0

itcast@ubuntu:~$ test

$var -gt 3

itcast@ubuntu:~$ echo$?1

itcast@ubuntu:~$ [

$var -gt 3 ]

itcast@ubuntu:~$ echo$?1

itcast@ubuntu:~$

雖然看起來很奇怪,但左方括號[確實是乙個命令的名字,傳給命令的各引數之間應該用空格隔開,比如,$var-gt3][命令的四個引數,它們之間必須用空格隔開。命令test或[的引數形式是相同的,只不過test命令不需要]引數。以[命令為例,常見的測試命令如下表所示:

[

-d dir ] 如果dir存在並且是乙個目錄則為真

[-f file ] 如果file存在且是乙個普通檔案則為真

[-z string ] 如果string的長度為零則為真

[-n string ] 如果string的長度非零則為真

[ string1 = string2 ] 如果兩個字串相同則為真

[ string1 != string2 ] 如果字串不相同則為真

[ arg1 op arg2 ] arg1和arg2應該是整數或者取值為整數的變數,op是-eq(等於)-ne(不等於)-lt(小於)-le(小於等於)-gt(大於)-ge(大於等於)之中的乙個

和c語言類似,測試條件之間還可以做與、或、非邏輯運算:

帶與、或、非的測試命令

[! expr ] expr可以是上表中的任意一種測試條件,!表示邏輯反

[ expr1 -a expr2 ] expr1和expr2可以是上表中的任意一種測試條件,-a表示邏輯與

[ expr1 -o expr2 ] expr1和expr2可以是上表中的任意一種測試條件,-o表示邏輯或

例如:

$ var=abc

$ [ -d desktop -a $var

='abc'

]$ echo

$?0

注意,如果上例中的$var變數事先沒有定義,則被shell展開為空字串,會造成測試條件的語法錯誤(展開為[ -d desktop -a = 'abc' ]),作為一種好的shell程式設計習慣,應該總是把變數取值放在雙引號之中(展開為[ -d desktop -a "" = 'abc' ]):

$ unset var

$ [ -d desktop -a $var

='abc'

]bash: [: too many arguments

$ [ -d desktop -a "$var"

='abc'

]$ echo

$?1

和c語言類似,在shell中用if、then、elif、else、fi這幾條命令實現分支控制。這種流程控制語句本質上也是由若干條shell命令組成的,例如先前講過的

if

[ -f ~/.bashrc ]

;then

. ~/.bashrc

fi

其實是三條命令,if [ -f ~/.bashrc ]是第一條,then . ~/.bashrc是第二條,fi是第三條。如果兩條命令寫在同一行則需要用;號隔開,一行只寫一條命令就不需要寫;號了,另外,then後面有換行,但這條命令沒寫完,shell會自動續行,把下一行接在then後面當作一條命令處理。和[命令一樣,要注意命令和各引數之間必須用空格隔開。if命令的引數組成一條子命令,如果該子命令的exit status為0(表示真),則執行then後面的子命令,如果exit status非0(表示假),則執行elif、else或者fi後面的子命令。if後面的子命令通常是測試命令,但也可以是其它命令。shell指令碼沒有{}括號,所以用fi表示if語句塊的結束。見下例:

#! /bin/sh

if[ -f /bin/bash ]

then

echo

"/bin/bash is a file"

else

echo

"/bin/bash is not a file"

fiif:;

then

echo

"always true"

;fi

:是乙個特殊的命令,稱為空命令,該命令不做任何事,但exit status總是真。此外,也可以執行/bin/true或/bin/false得到真或假的exit status。再看乙個例子:

#! /bin/sh

echo

"is it morning? please answer yes or no."

read yes_or_no

if["$yes_or_no"

="yes"];

then

echo

"good morning!"

elif

["$yes_or_no"

="no"];

then

echo

"good afternoon!"

else

echo

"sorry, $yes_or_no not recognized. enter yes or no."

exit 1

fiexit 0

上例中的read命令的作用是等待使用者輸入一行字串,將該字串存到乙個shell變數中。

此外,shell還提供了&&和||語法,和c語言類似,具有short-circuit特性,很多shell指令碼喜歡寫成這樣:

test

"$(whoami)"

!='root'

&&(echo you are using a non-privileged account;

exit 1)

&&相當於「if…then…」,而||相當於「if not…then…」。&&和||用於連線兩個命令,而上面講的-a和-o僅用於在測試表示式中連線兩個測試條件,要注意它們的區別,例如:

test

"$var" -gt 1 -a "$var" -lt 3

和以下寫法是等價的

test

"$var" -gt 1 &&

test

"$var" -lt 3

case/esac

case命令可模擬c語言的switch/case語句,esac表示case語句塊的結束。c語言的case只能匹配整型或字元型常量表示式,而shell指令碼的case可以匹配字串和wildcard,每個匹配分支可以有若干條命令,末尾必須以;;結束,執行時找到第乙個匹配的分支並執行相應的命令,然後直接跳到esac之後,不需要像c語言一樣用break跳出。

#! /bin/sh

echo

"is it morning? please answer yes or no."

read yes_or_no

case

"$yes_or_no"

inyes

|y|yes|yes)

echo

"good morning!";;

[nn]*)

echo

"good afternoon!";;

*)echo

"sorry, $yes_or_no not recognized. enter yes or no."

exit 1;

; esac

exit 0

使用case語句的例子可以在系統服務的指令碼目錄/etc/init.d中找到。這個目錄下的指令碼大多具有這種形式(以/etc/init.d/nfs-kernel-server為例):

case

"$1"

in start)

... ;

; stop)

... ;

; reload | force-reload)

... ;

; restart)

... *)

log_success_msg "usage: nfs-kernel-server "

exit 1

;; esac

啟動nfs-kernel-server服務的命令是

$ sudo /etc/init.d/nfs-kernel-server start

Shell 學習10 Shell 注釋

以 開頭的行就是注釋,會被直譯器忽略。sh裡沒有多行注釋,只能每一行加乙個 號。只能像這樣 這是乙個自動打ipa的指令碼,基於webfrogs的ipa build書寫 特色 全自動打包,不需要輸入任何引數 使用者配置區 開始 專案根目錄,推薦將此指令碼放在專案的根目錄,這裡就不用改了 使用者配置區 ...

shell條件測試

shell條件測試通常都會用在for while until if等控制流結構中,用於判斷檔案的相關性質或變數的相互關係。條件測試用法 test 表示式 結果 成立返回0,不成立返回非0 檢視結果 echo 以下是幾類常用的測試表示式 1 檔案狀態測試 b filename 當filename 存在...

shell條件測試

shell條件測試 檔案狀態測試 b filename 當filename 存在並且是塊檔案時返回真 返回0 c filename 當filename 存在並且是字元檔案時返回真 d pathname 當pathname 存在並且是乙個目錄時返回真 e pathname 當由pathname 指定的...