3 回答

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超6個贊
bool=true
if [ "$bool" = true ]
有三苦的(問題原)答案
我不推薦接受的答案1。它的語法很漂亮,但是有一些缺陷。
說我們有以下情況。
if $var; then
echo 'Muahahaha!'
fi
在以下情況2中,此條件將評估為true并執(zhí)行嵌套命令。
# Variable var not defined beforehand. Case 1
var='' # Equivalent to var="". Case 2
var= # Case 3
unset var # Case 4
var='<some valid command>' # Case 5
通常,僅在您的“布爾”變量(var在此示例中)顯式設(shè)置為true 時,才希望條件評估為true。所有其他情況都是危險的誤導(dǎo)!
最后一種情況(#5)特別頑皮,因?yàn)樗鼘?zhí)行變量中包含的命令(這就是為什么條件對于有效命令3、4評估為true的原因)。
這是一個無害的示例:
var='echo this text will be displayed when the condition is evaluated'
if $var; then
echo 'Muahahaha!'
fi
# Outputs:
# this text will be displayed when the condition is evaluated
# Muahahaha!
引用變量更安全,例如if "$var"; then。在上述情況下,您應(yīng)該得到一條警告,提示找不到該命令。但是我們?nèi)匀豢梢宰龅酶茫ㄕ垍㈤喌撞康慕ㄗh)。
另請參閱Mike Holt對Miku原始答案的解釋。
Hbar的答案有問題
這種方法也具有意外的行為。
var=false
if [ $var ]; then
echo "This won't print, var is false!"
fi
# Outputs:
# This won't print, var is false!
您可能希望上述條件的計(jì)算結(jié)果為false,從而從不執(zhí)行嵌套語句。驚喜!
引用值("false"),引用變量("$var")或使用test或[[代替[都沒有區(qū)別。
我的建議:
我建議您通過以下方法檢查“布爾值”。他們按預(yù)期工作。
bool=true
if [ "$bool" = true ]; then
if [ "$bool" = "true" ]; then
if [[ "$bool" = true ]]; then
if [[ "$bool" = "true" ]]; then
if [[ "$bool" == true ]]; then
if [[ "$bool" == "true" ]]; then
if test "$bool" = true; then
if test "$bool" = "true"; then
它們幾乎相等。您將需要比其他答案5中的方法鍵入更多的擊鍵,但是您的代碼將更具防御性。
腳注
此后,Miku的答案已被編輯,不再包含(已知)缺陷。
并非詳盡的清單。
在此上下文中,有效命令表示存在的命令。命令的使用正確與否無關(guān)緊要。例如man woman,即使不存在這樣的手冊頁,它也仍然被視為有效命令。
對于無效(不存在)的命令,Bash只會抱怨找不到該命令。
如果您在意長度,則第一個建議是最短的。

TA貢獻(xiàn)1790條經(jīng)驗(yàn) 獲得超9個贊
關(guān)于Bash內(nèi)置函數(shù)true,尤其是Bash如何擴(kuò)展和解釋方括號內(nèi)的表達(dá)式,這里似乎存在一些誤解。
miku的答案中的代碼與內(nèi)置的Bash true,nor /bin/true或true命令的任何其他形式完全無關(guān)。在這種情況下,true是不是一個簡單的字符串罷了,以及無呼叫true命令/內(nèi)置是有史以來,既不是變量賦值,也不由條件表達(dá)式的評價。
以下代碼在功能上與miku答案中的代碼相同:
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
的唯一這里不同的是,四個字符被比較是“Y”,“E”,“A”,并且代替“T”“H”,“R”,“U”,和“e”的。而已。yeah在Bash解析令牌時,沒有嘗試調(diào)用名為named的命令或內(nèi)置命令,也沒有進(jìn)行任何形式的特殊處理(在miku的示例中)true。它只是一個字符串,并且完全是任意的。
更新(2014-02-19):跟隨miku的答案中的鏈接之后,現(xiàn)在我看到了一些混亂的來源。Miku的答案使用單括號,但他鏈接到的代碼段不使用括號。只是:
the_world_is_flat=true
if $the_world_is_flat; then
echo 'Be careful not to fall off!'
fi
這兩個代碼段的行為方式相同,但是括號完全改變了引擎蓋下發(fā)生的事情。
這是Bash在每種情況下所做的事情:
沒有括號:
將變量$the_world_is_flat擴(kuò)展為字符串"true"。
嘗試將字符串解析"true"為命令。
查找并運(yùn)行true命令(內(nèi)置命令或/bin/true,具體取決于Bash版本)。
將true命令的退出代碼(始終為0)與0進(jìn)行比較?;叵胍幌?,在大多數(shù)shell中,退出代碼0表示成功,而其他任何代碼則表示失敗。
由于退出代碼為0(成功),因此執(zhí)行if語句的then子句
括號:
將變量$the_world_is_flat擴(kuò)展為字符串"true"。
解析現(xiàn)在已經(jīng)擴(kuò)展的條件表達(dá)式,其形式為string1 = string2。該=運(yùn)算符是bash的字符串比較運(yùn)算符。所以...
在"true"和上進(jìn)行字符串比較"true"。
是的,兩個字符串相同,因此條件的值是true。
執(zhí)行if語句的then子句。
無括號代碼有效,因?yàn)樵搕rue命令返回的退出代碼為0,表示成功。括號內(nèi)的代碼有效,因?yàn)榈闹?the_world_is_flat與true右側(cè)的字符串文字相同=。
只是為了說明問題,請考慮以下兩個代碼段:
此代碼(如果以root特權(quán)運(yùn)行)將重新引導(dǎo)計(jì)算機(jī):
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
此代碼僅顯示“ Nice try”。重新啟動命令不被調(diào)用。
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
更新(2014年4月14日)要回答在評論有關(guān)之間的差異問題=和==:據(jù)我所知,沒有任何區(qū)別。該==運(yùn)營商特定的Bash-代名詞=,而據(jù)我所看到的,他們的工作完全一樣在所有上下文中。
但是請注意,我是專門討論在或測試中使用的=和==字符串比較運(yùn)算符。我不建議這樣做,并且在bash中到處都是可以互換的。[ ][[ ]]===
例如,您顯然不能使用進(jìn)行變量賦值==,例如var=="foo"(從技術(shù)上講,您可以這樣做,但是varwill 的值是"=foo",因?yàn)锽ash ==在這里沒有看到運(yùn)算符,而是看到了=(賦值)運(yùn)算符,然后是文字值="foo",變成"=foo")。
另外,盡管=和==可以互換,但是您應(yīng)該記住,這些測試的工作方式確實(shí)取決于您是在[ ]還是內(nèi)部使用它[[ ]],還取決于是否引用了操作數(shù)。你可以閱讀更多關(guān)于高級Bash腳本編程指南:7.3其他比較操作符(向下滾動到的討論=和==)。
添加回答
舉報