2015-08-25 24 views
0

我有一個帶有errexit選項的shell腳本。我怎樣才能否定腳本內的命令的返回碼,所以我可以預料它會失敗?具有否定返回碼的殼errexit

$ cat a 
#!/bin/sh 
set -o errexit -o xtrace 
! true 
echo Oook. 

$ ./a 
+ true 
+ echo Oook. 
Oook. 

echo命令不應執行。

+0

具體而言,我需要否定'grep -qr'命令。 – zakjan

+0

你需要做什麼?當'grep'找到你的內容時失敗? –

+0

是的。一個簡單的檢查另一個應用程序的源代碼。 – zakjan

回答

2

據我可以告訴你不能。

spec

-e 當這個選項時,當任何命令失敗(對於任何的殼牌錯誤的後果或通過返回一個退出狀態大於零列出的原因),該殼立即應符合下列退出例外: 多命令管道中任何單個命令的失敗都不應導致shell退出。只應考慮管道本身的故障。

在執行復合列表時執行復合列表時忽略-e設置,直到,如果或者elif保留字,以!保留字或除最後一個以外的AND-OR列表的任何命令。

如果sub-shell命令以外的複合命令的退出狀態是-e被忽略時失敗的結果,則-e不適用於此命令。

該要求分別適用於shell環境和每個子shell環境。例如,在:

set -e; (false; echo one) | cat; echo two 

false命令會導致subshel​​l不執行echo one而退出;但是,由於管道的退出狀態(false; echo one)|,所以會執行echo two貓是零。

這是人們經常暗示不使用errexit的衆多原因之一。它只是不夠可靠,太容易「易碎」。

正如拉爾斯表示註釋這種情況的解決方法是使用

maybe-true || false 

maybe-true && exit 
+0

我已經通過將命令包裝到子shell中解決了它。看到我的答案。 – zakjan

+0

這有效,但更昂貴。 –

0

您應該簡單地調查grep的退出狀態,這是0時,比賽是發現1,如果找不到匹配,則返回1,如果發生錯誤,則返回2,然後將退出狀態變爲任何適合您需要的狀態:

grep -q "$regex" file 
stat=$? 
case $stat in 
    (0) echo found; exit 1;; 
    (1) echo not found; exit 0;; 
    (2) echo error; exit 2;; 
    (*) echo something unexpected; exit $stat;; 
esac 
0

我已經通過將命令包裝到子shell中解決了它。

$ cat a 
#!/bin/sh 
set -o errexit -o xtrace 
(! true) 
echo Oook. 

$ ./a 
+ true