在 bash 中運行exec echo "some "; echo "test"
永遠不會列印“一些測試”嗎?
我會尋求對這個問題的確認,因為我正在編寫一個小 shell 腳本,並且我希望它在exec
呼叫命令後不繼續執行任何操作。
我想我是不用擔心的,根據我的了解,諮詢後:
man 3 exec
man 1p exec
shell 腳本在由 shell 執行時將使得
- shell執行程序
exec
,其中 - 使用
exec***
系列系統呼叫來取代正在執行腳本的 shell/bash,這樣阻礙shell 的進一步操作(被「取代」)
如前所述,這個問題的主要目標是尋求對我的推理的確認,以防止echo test
執行 exec 之後發生的腳本中的任何內容(例如 )。
我希望盡可能得到一般性答案(POSIX),但以防萬一,我對 GNU/Linux 和 GNU/Bash 最感興趣
答案1
對了,如果exec
成功的話,它會取代當前的shell,所以下面的命令不會,err..執行。
然而,至少在 Bash 中,如果exec
失敗:
exec [-cl] [-a name] [command [arguments]]
如果命令提供後,它會取代 shell,而不建立新進程。 [...] 如果命令由於某種原因無法執行,非互動式 shell 退出,除非
execfail
啟用了 shell 選項。在這種情況下,它會回傳失敗。
因此,即使是類似的東西也bash -c 'exec /bin/nosuchfile; echo foo'
只會列印一條有關遺失程式檔案的錯誤訊息。要處理腳本中的錯誤,您需要類似的東西
#!/bin/bash
shopt -s execfail
exec /someprogram
echo whoops, it failed
但是,您仍然收到來自 的錯誤訊息exec
。如果您對 進行重定向exec
,它仍然有效如果腳本在exec
失敗後繼續。
答案2
內建exec
函數(帶有命令參數 1)取代了 shell 進程 2。 shell進程中的後續程式碼不會被執行。
exec echo "some "; echo "test"
因此,列印的唯一方法是如果在 PATH 中some text
呼叫了一個可執行命令,並且列印了該可執行檔而不是.在正常情況下,這種情況不會發生,因為可執行檔案的行為與名為 的命令的預期相同。echo
some text
some
echo
echo
echo
如果PATH 中沒有呼叫執行檔或執行失敗,exec
則會顯示錯誤訊息並退出 shell。即使在這種情況下,echo "test"
也不會被執行。
沒有命令參數是一個不同的野獸。它不會取代 shell 進程,它只是應用重定向。
²在子shell中,只有子shell受到影響,父shell保持正常運作。 exec
答案3
exec
總是完成腳本如果它執行命令並成功執行(與命令的退出代碼無關,但與啟動它相關)。
exec
可以在沒有命令的情況下以非常有用的方式運行:永久重定向檔案描述符:
exec 3>/path/to/file
如果該命令無法啟動,則 shell 行為取決於配置。bash
預設退出。
您最好使用函數來代替:
safe_exec () {
cmd="$1"
if test -z "$cmd" || ! test -f "$cmd" || ! test -x "$cmd"; then
exit 1
else
exec "$@"
fi
}
safe_exec echo "some "; echo "test"