2012-06-18 60 views
1

在此question中已經顯示瞭如何在bash中使用整型布爾變量。有沒有辦法用這些變量來執行邏輯運算?例如。如何得到這個:對布爾變量的操作

var1=true 
var2=false 
# ...do something interesting... 
if ! $var1 -a $var2; then  <--- doesn't work correctly 
    echo "do sth" 
fi 

回答

7

這並不工作:

if ! $var1 && $var2; then 
    echo "do sth" 
fi 

也許有人可以解釋爲什麼-a和-o運營商不工作,& &,||!做?

+5

-a和-o是來自舊Bourne shell的'test'命令(您沒有使用)的運算符,並且已經過時。 &&和!是bash語法的一部分。 – cdarke

1

這裏混合了兩種不同的語法。

這將工作:圍繞表達式

if ! [ 1 -a 2 ]; then 
    echo "do sth" 
fi 

注意括號。

您需要test命令([採用更新的語法)才能使用這些密鑰(-a,-o等)。

但是test本身也會執行螺母運行命令。 如果你想檢查命令的退出代碼,你不能使用test

+2

不,'['和'test'或多或少同時出現,都很舊。 「較新」的條件構造是'[[',Bash,ksh和zsh支持。 'test'不運行命令,而是'if'(因爲'test','['和'[['是命令而不是語法元素)。 –

+0

@Dennis:我的意思是你不能寫'if [$ var1 -a $ var2]'因爲'test'不運行命令。 –

5

好的男孩和女孩,課時。

執行此行時發生了什麼?

if true ; then echo 1 ; fi 

這裏發生的事情是,正在執行的if命令。之後,發生的一切都是if命令的一部分。

if做什麼是它執行一個或多個命令(或者更確切地說,管道),如果從最後執行的命令的返回碼是成功的,它是達到then直到fi後執行的命令。如果返回代碼不成功,則跳過then部件,並在fi之後繼續執行。

if不需要開關,它的行爲無論如何都是不可修改的。

在上例中,我告訴if執行的命令是truetrue不是語法或關鍵字,它只是另一個命令。嘗試通過自身執行它:

true 

它將打印什麼,但它設置它的返回碼0(又名「真」)。你可以更清楚地看到,它是一個命令通過改寫上述if聲明是這樣的:

if /bin/true ; then echo 1 ; fi 

這是完全等價的。

總是從測試中返回true不是很有用。通常將iftest命令結合使用。test有時符號鏈接或以其他方式被稱爲[。在你的系統上,你可能有一個/bin/[程序,但是如果你使用的是bash[將是一個內置命令。 test是一個比if更復雜的命令,你可以閱讀所有關於它的內容。

help [ 
man [ 

但現在讓我們說,test根據您提供與任何一個成功的返回碼(0)或不成功的一個回報率的選項進行一些測試。這讓我們說

if [ 1 -lt 2 ] ; then echo one is less than two ; fi 

但同樣,這是總是真實的,所以它不是非常有用的。這將是更爲有用,如果12是變量

read -p' Enter first number: ' first 
read -p' Enter second number: ' second 
echo first: $first 
echo second: $second 
if [ $first -lt $second ] ; then 
    echo $first is less than $second 
fi 

現在你可以看到test正在做的工作。這裏我們通過test四個參數。第二個參數是-lt,它是一個開關,告訴test應該測試第一個參數和第三個參數,以查看第一個參數是否小於第三個參數。第四個參數只是標記命令的結尾;當致電test作爲[時,最後的參數必須始終爲]

在執行上面的if語句之前,會對變量進行評估。假設我已經進入了20 first和25 second,評估後的腳本將是這樣的:

read -p' Enter first number: ' first 
read -p' Enter second number: ' second 
echo first: 20 
echo second: 25 
if [ 20 -lt 25 ] ; then 
    echo 20 is less than 25 
fi 

現在你可以看到,當test執行將測試is 20 less than 25?,這是真的,那麼if將執行then聲明。

回到手頭的問題:這裏發生了什麼?

var1=true 
var2=false 

if ! $var1 -a $var2 ; then 
    echo $var1 and $var2 are both true 
fi 

if命令被評估它將成爲

if ! true -a false ; then 

這被指示if執行true和傳遞的參數-a falsetrue命令。現在,true不會接受任何開關或參數,但如果您不需要提供它們,它也不會產生錯誤。這意味着它將執行,返回成功,並且-a false部分將被忽略。 !將使成功進入失敗狀態,並且then部分將不會執行。

如果你有一個版本叫test來代替上述根據需要也仍然無法工作:

var1=true 
var2=false 

if ! [ $var1 -a $var2 ] ; then 
    echo $var1 and $var2 are both true 
fi 

因爲if線將進行評估,以

if ! [ true -a false ; ] then 

而且test會看到true不作爲布爾關鍵字,不作爲命令,而是作爲字符串。由於非空字符串由test爲「真」對待它總是返回成功if,即使你曾說過

if ! [ false -a yourmom ] ; then 

由於都是非空字符串-a測試都爲真,返回成功這與!相反,並傳遞給if,後者不執行then聲明。

如果您使用此版本

if ! $var1 && $var2 ; then 

,然後更換test版本,它會進行評估,以

if ! true && false ; then 

而且會處理這樣的:if執行true返回成功;這被!逆轉;因爲第一個命令的返回代碼失敗,&&語句短路和false從未得到執行。由於執行的最終命令返回了故障,因此故障將傳回至if,該故障不會執行then子句。

我希望這一切都清楚。

或許值得指出的是,你可以使用結構是這樣的:

! false && true && echo 1 

不使用if但還是檢查返回代碼,因爲這是&&||是。

在沒有犯任何錯誤的情況下使用test有一種黑色藝術。通常,在使用bash時,應該使用較新的[[命令,因爲它的功能更強大,並且爲了兼容性原因必須保留在[之內。

由於原始海報沒有提供他想要完成的實際例子,所以很難就最佳解決方案給出任何具體建議。希望這對他現在能夠找出正確的事情有足夠的幫助。