Pipe

鍊式命令的退出狀態

  • May 16, 2019

我想在變數中執行一個可能無效的命令cmd。我不能讓它失敗並檢索退出狀態。我可以嘗試做的是將它傳送到:,然後我將獲得成功的退出狀態。

$ $cmd | :
$ echo $?
0

現在,我想知道cmd不執行它的退出狀態。在 Bash 中,我可以使用PIPESTATUS. 但我正在使用破折號。

我試圖執行bash -c "$cmd | : ; rc=$(echo ${PIPESTATUS[@]} | head -c1)",但我得到一個“Bad substituion error”。

我的問題是:

  1. 如何實現我在破折號中返回第一個命令的退出狀態的目標?
  2. 我正在做什麼會在破折號中產生錯誤?

如果您有完整的 shell 語法可用,那麼您可以使用if,這不會顯示為 shell 失敗:

if (eval "$cmd"); then
   : # do nothing, it worked
else
   printf 'Command %s failed with code %d\n' "$cmd" $?
fi

請注意,您不能使用更明顯的if ! eval…語法,因為否定將隱藏退出程式碼。那裡有“什麼都不做”位,因為 shell 語法需要一個帶有命令的 then 塊;您不能省略它或將其留空。

重要的是if,即使評估的命令失敗,shell 也不會失敗。

括號是在子shell中執行命令;這可以防止命令設置影響腳本的變數或執行類似exit 1完全終止腳本的操作。

最後,請注意我是如何使用eval而不是 unquoted 的$cmd。那是因為未引用的命令以您可能不期望的方式進行分詞。如果您有cmd='rm -Rf "foo * baz"',那麼當您執行時$cmd,您實際執行的是rm -Rf \"foo * baz\"-它將擴展*到目錄中的所有文件,刪除所有內容(除了兩個文件"foobaz")。這是全域擴展之前的三個參數rm,而不是您期望的參數。eval將應用正常的 shell 命令解析,我認為會導致更少的驚喜。如果這是在您的腳本中建構的命令而不是例如從文本文件中讀取的行,則還有其他方法(例如使用數組)更安全。

引用自:https://unix.stackexchange.com/questions/519275