2012-03-27 42 views
0

我開始在我的bash腳本中使用set -e, ,並發現短格式的條件表達式會中斷腳本執行。當使用set時,bash單行條件失敗-e

例如,下面的線應該檢查是$ var不爲空:

[ -z "$var" ] && die "result is empty" 

但導致從腳本無聲退出時是$ var具有非零長度。

我曾經在許多地方,這種形式的條件表達式...

我應該怎麼做,使之正常運行?用「if」構造重寫所有內容(這會很醜陋)?或放棄「set -e」?

編輯:大家都在問代碼。這裏充滿[無]工作示例:

#!/bin/bash 
set -e 

function check_me() 
{ 
    ws="smth" 
    [ -z "$ws" ] && echo " fail" && exit 1 
} 

echo "checking wrong thing" 
check_me 
echo "check finished" 

我希望它之前和之後的函數調用打印兩相呼應。 但它在check_me函數中靜靜失敗。輸出是:

checking wrong thing 
+0

你在哪裏使用'set -e'?顯示完整的代碼。 – 2012-03-27 08:46:53

+0

你所描述的不應該發生(我不能再現)。這是專門列出的情況下shell不會退出手冊頁。 – Mat 2012-03-27 08:49:46

+0

這可能是在這裏有意義的用法。我已經添加了一個示例腳本(完整)。 – LiMar 2012-03-27 09:09:09

回答

5

使用

[ -n "$var" ] || die "result is empty" 

這樣一來,整個語句的返回值是true,如果$var非空,所以ERR陷阱不會被觸發。

+0

@LiMar:你期望一個叫做'die'的函數能夠返回嗎? – ams 2012-03-27 09:26:46

+0

@ams:不,我不知道。這只是一個「回聲」,接着是「退出1」的包裝。 – LiMar 2012-03-27 09:30:57

+1

@LiMar:因此,如果測試返回false,它將調用死亡,並且一切都將按預期工作。如果測試返回true,那麼腳本將繼續。我在這裏看不到你的問題? – ams 2012-03-27 09:33:34

2

您應該編寫腳本,以避免命令以非零狀態退出。

在你的命令[ -z "$var" ]可以是真的,在這種情況下,你可以撥打die,或者在這種情況下-e是真的。

要麼與if寫,就像你說的,還是用這樣的:

[ -z "$var" ] && die "result is empty" || true 

我建議if雖然。

+0

As @ I0b0表示,這個具體示例有一個更漂亮的方法,但上面的方法適用於任何事情。 – ams 2012-03-27 09:16:23

+0

[對此非常謹慎](http://mywiki.wooledge.org/BashPitfalls#cmd1_.26.26_cmd2_.7C.7C_cmd3)。在這種情況下,它可能會起作用,但要知道如果這些命令不重要,效果將會變得非常棘手。 – l0b0 2012-03-27 09:21:26

+0

這就是爲什麼我建議'如果'。 – ams 2012-03-27 09:25:39

2

恐怕你不得不重寫所有內容,以免發生虛假陳述。

set -e定義很明確:如果

-e立即退出一個簡單的命令(見以上SHELL文法)具有非零狀態退出。如果失敗的命令是命令列表的一部分,緊接着一段時間或直到關鍵字,if語句中的測試的一部分,或者是一個&或更高版本的一部分,則shell不會退出。列表,或者命令的返回值是否通過!來反轉。如果設置了ERR,則會在shell退出之前執行陷阱。

你正在使用bash的「優化」系統:因虛假陳述將導致AND(&&)語句永遠是真實的,慶典知道它沒有執行該行的第二部分。但是,這是對系統的一種巧妙的「濫用」,並非意欲的行爲,因此與set -e不兼容。您將不得不重寫所有內容,以便使用正確的if s。