Bash

兼容性腳本:節省 $?供以後使用

  • January 24, 2015

我想寫一小部分腳本來保存錯誤狀態,執行一些其他程式碼,並將錯誤狀態設置為原始錯誤狀態。在 Bash 中,它看起來像這樣:

<< some command >>; _EXIT=$?;( <<other code here>> ;exit $_EXIT)

但我需要能夠執行的程式碼,無論它是在 bash、zsh、csh 還是 tcsh 下執行。我不知道會提前使用哪個shell,因為它是由使用者決定的。使用者還決定<< some command >>。

假設 << other code >> 將在所有 shell 中工作是安全的,但假設您可以編寫文件是不安全的(因此將其放入文件中是行不通的)。

背景

GNU Parallel 在使用者決定的 shell 中執行使用者給出的命令。命令完成後,GNU Parallel 需要進行一些清理工作。同時 GNU Parallel 需要記住使用者給出的命令的退出值。在上面的程式碼片段之前執行的程式碼是使用者給定的命令。<< other code >> 是清理程式碼。

使用 perl:

perl -e '$a=shift; `&lt;&lt; other code &gt;&gt;`; exit $a' $? # Fails in csh

編輯這也適用於 csh(以及 zsh、tcsh、sh、pdksh、ksh93 - 雖然不是魚):

perl -e '$a=shift; `&lt;&lt; other code &gt;&gt;`; $a=~s/h// and exit $a; exit shift' "$?h" "$status"

這個答案適用於類似 bash 的 shell 和類似 csh 的 shell,並且不需要 perl:

sh -c '&lt;&lt; other code &gt;&gt;; [ "$0" != "" ] && exit "$0"; exit "$1"' "$?" "$status"

或者您可以添加一個 dummy/pad 參數:

sh -c '&lt;&lt; other code &gt;&gt;; [ "$1" != "" ] && exit "$1"; exit "$2"' foo "$?" "$status"

並且可以將測試更改為[ ! -z "$0" ](或"$1")。我不知道它是否適用於zsh或fish。我熟悉的每個 shell 都會在解析命令時進行評估$?,並將它們作為參數$status 傳遞給命令。sh -cshell將sh它們分配給最後兩個位置參數。當“其他程式碼”完成時,shell 將檢查從中$?獲取其值的位置參數,看它是空還是非空,並以適當的位置參數值退出。

如果環境外殼使用的東西不是$?$status 保持退出狀態,這將失敗。$?如果 shell 允許設置(非空),如果它不是退出狀態,或者如果$?是導致整個命令被拒絕為語法錯誤的無效字元序列,它也會失敗。

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