命令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
、-gt
、3
、]
是[
命令的四個引數,它們之間必須用空格隔開。命令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 指定的...