2010-09-03 33 views
17

我需要在我的bash腳本中捕獲命令的輸出和錯誤,並知道命令是否成功。bash變量分別捕獲標準錯誤和stdout或獲取退出值

此刻,我喜歡這個拍攝兩個:

output=$(mycommand 2>&1) 

然後我需要檢查mycommand的出口值。如果失敗了,我需要用輸出做一些事情,如果命令成功了,我不需要觸摸輸出。

由於我捕獲輸出,檢查$?總是一個0,因爲bash成功地將輸出捕獲到變量中。

這是一個非常時間敏感的劇本,所以我們試圖避免像輸出到文件並重新閱讀它在任何速度較慢的解決方案。

如果我能標準輸出捕獲到一個變量和標準錯誤到另一個,這將解決我的問題,因爲我可以檢查錯誤變量是否爲空。

謝謝。

+4

見[BashFAQ/002](http://mywiki.wooledge.org/BashFAQ/002)和[BashFAQ/047](http://mywiki.wooledge.org/BashFAQ/047)。 – 2010-09-03 03:29:24

回答

8

您使用的是bash的哪個版本?輸出的捕獲對返回代碼與我的版本效果,4.1.5

pax> false; echo $? 
1 
pax> echo $? 
0 
pax> x=$(false 2>&1) ; echo $? 
1 

這並不總是依賴於標準錯誤是非空探測的錯誤是一個好主意。許多程序不會輸出錯誤,而是僅依賴於返回碼上的

+0

我忘了提及我將命令的輸出傳送給另一個。儘管我可以在單獨的命令後在病房後面這樣做。謝謝。 – mhost 2010-09-03 03:35:19

+3

小心!有'local x = $(false 2> &1) ; echo $?'或'set x = $(false 2> &1) ; echo $?'(note **'開始處的local/set' **)不輸出'0' '1'作爲最後一個命令運行的是'local/set' – 2013-06-18 10:38:22

10

問題似乎只當輸出被捕獲到函數內的本地變量來體現:

$ echo $BASH_VERSION 
3.2.48(1)-release 
$ false; echo $? 
1 
$ echo $? 
0 
$ x=$(false 2>&1) ; echo $? 
1 
$ function f { 
> local x=$(false 2>&1) ; echo $? 
> } 
$ f 
0 
$ function g { 
> x=$(false 2>&1) ; echo $? 
> } 
$ g 
1 

注意,只有函數f,其捕獲x到一個地方,可以表達的行爲。特別是,執行相同的事情,但沒有「本地」關鍵字的函數g起作用。

因此可以不使用局部變量,也可能在使用後「取消」它。

EDIT NVRAM指出局部聲明可以預先製成,以避免該問題:

$ function h { 
> local x 
> x=$(false 2>&1) ; echo $? 
> } 
$ h 
1 
+0

非常有趣!這發生在bash和dash(posix)shell。 – Gregor 2011-10-19 15:00:46

+3

實際上$?是爲局部變量聲明設置的,如果你只是聲明它本身,然後_分配它在一個單獨的行它將工作,就是你想要的。換句話說,添加**本地x **在您的行上面** x = ** – NVRAM 2012-01-31 16:30:00