兼容性腳本:節省 $?供以後使用
我想寫一小部分腳本來保存錯誤狀態,執行一些其他程式碼,並將錯誤狀態設置為原始錯誤狀態。在 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; `<< other code >>`; exit $a' $? # Fails in csh
編輯這也適用於 csh(以及 zsh、tcsh、sh、pdksh、ksh93 - 雖然不是魚):
perl -e '$a=shift; `<< other code >>`; $a=~s/h// and exit $a; exit shift' "$?h" "$status"
這個答案適用於類似 bash 的 shell 和類似 csh 的 shell,並且不需要 perl:
sh -c '<< other code >>; [ "$0" != "" ] && exit "$0"; exit "$1"' "$?" "$status"
或者您可以添加一個 dummy/pad 參數:
sh -c '<< other code >>; [ "$1" != "" ] && exit "$1"; exit "$2"' foo "$?" "$status"
並且可以將測試更改為
[ ! -z "$0" ]
(或"$1"
)。我不知道它是否適用於zsh或fish。我熟悉的每個 shell 都會在解析命令時進行評估$?
,並將它們作為參數$status
傳遞給命令。sh -c
shell將sh
它們分配給最後兩個位置參數。當“其他程式碼”完成時,shell 將檢查從中$?
獲取其值的位置參數,看它是空還是非空,並以適當的位置參數值退出。如果環境外殼使用的東西不是
$?
或$status
保持退出狀態,這將失敗。$?
如果 shell 允許設置(非空),如果它不是退出狀態,或者如果$?
是導致整個命令被拒絕為語法錯誤的無效字元序列,它也會失敗。