在 bash 中運行“exec echo some; echo test”永遠不會打印“some test”嗎?

在 bash 中運行“exec echo some; echo test”永遠不會打印“some test”嗎?

在 bash 中運行exec echo "some "; echo "test"永遠不會列印“一些測試”嗎?

我會尋求對這個問題的確認,因為我正在編寫一個小 shell 腳本,並且我希望它在exec呼叫命令後不繼續執行任何操作。

我想我是不用擔心的,根據我的了解,諮詢後:

  • man 3 exec
  • man 1p exec

shell 腳本在由 shell 執行時將使得

  1. shell執行程序exec,其中
  2. 使用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呼叫了一個可執行命令,並且列印了該可執行檔而不是.在正常情況下,這種情況不會發生,因為可執行檔案的行為與名為 的命令的預期相同。echosome textsomeechoecho

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"

相關內容