我在檢查多管道命令鏈中的某個命令是否發生錯誤時遇到問題。通常這不難檢查,但set -o pipefail
和檢查${PIPESTATUS[@]}
都不適用於我的情況。設置是這樣的:Bash:檢查多管道命令鏈的退出狀態
cmd="$snmpcmd $snmpargs $agent $oid | grep <grepoptions> for_stuff | cut -d',' f$fields | sed 's/ubstitute/some_other_stuff/g'"
注意1:該命令進行了徹底測試,並完美地工作。
現在,我想將該命令的輸出存儲在名爲procdata
的數組中。因此,我所做的:
declare -a procdata
procdata=($(eval $cmd))
注2:eval
是必要的,因爲否則$snmpcmd
與invalid option -- <grepoption>
錯誤,是沒有意義的,因爲<grepoption>
不是$snmpcmd
選項明顯拋出了。在這個階段,我認爲這是一個錯誤$snmpcmd
,但這是另一個節目...
如果發生錯誤,procdata
將爲空。但是,由於兩種不同的原因,它可能爲空:要麼是因爲在執行$snmpcmd
時發生錯誤(例如超時),要麼是因爲grep
找不到要查找的內容。問題是,我需要能夠區分這兩種情況並分別處理它們。
因此,set -o pipefail
不是一個選項,因爲它會傳播任何錯誤,我無法區分哪部分管道失敗。另一方面echo ${PIPESTATUS[@]}
總是0
後procdata=($(eval $cmd))
即使我有很多管道!然而,如果我在提示符處直接執行整個命令,並立即調用echo ${PIPESTATUS[@]}
,它將正確返回所有管道的退出狀態。
我知道我可以將err流綁定到標準輸出,但我必須使用啓發式方法來檢查procdata
中的元素是否有效或錯誤消息,並且我冒着獲得誤報的風險。我也可以將stdout管道輸入到/dev/null
並只捕獲錯誤流並檢查是否${#procdata[@]} -eq 0
。但我不得不重複這個呼叫來獲取實際數據,整個命令的時間成本很高(大約3-5s)。我不想打兩次電話。或者我可以使用一個臨時文件來寫錯誤,但我寧願這樣做,而沒有創建/刪除文件的開銷。
任何想法,我可以使這項工作在bash?
感謝
PS:
$ echo $BASH_VERSION
4.2.37(1)-release
我有同樣的想法。不幸的是它不起作用,但我不知道爲什麼。我發佈了確切的命令,因爲我可能看不到明顯的: – user3040975
'local cmdargs =「 - CHf,-m $ mibs -v $ snmpver -c $ community $ agent」; local procdatacmd =「$ tblcmd $ cmdargs $ proc_table」; procdatacmd + =「| cut -d','-f $ fields | grep -we -e | sort | uniq -c | sed's/^ * \ | \」// g; s //,/ g' ; echo $ {PIPESTATUS [@]}「'然後執行:'declare -a procdata =($(head -n-1 <<< $ $ procdatacmd))'輸出是空的......只是沒有。 –
user3040975
@ user3040975你似乎沒有_running_上面的行中有任何命令 – devnull