`{ { (exit 1); 是什麼意思? 1號出口; }; }` 是什麼意思?

`{ { (exit 1); 是什麼意思? 1號出口; }; }` 是什麼意思?

config.status我引用了生成的下一個程式碼片段configure

if test ! -f "$as_myself"; then
{ { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
{ (exit 1); exit 1; }; }
fi

程式碼片段中,{ (exit 1); exit 1; };做了什麼?只exit在子 shell 中執行的目的是什麼?

答案1

執行(exit 1);是觸發陷阱最簡單的方法ERR。如果set -e有效,它也會觸發立即退出。 (觸發錯誤條件需要命令失敗;exit子 shell 中的失敗值會導致子 shell 失敗。)

exit 1;不會做這兩件事。

So{(exit 1); exit 1;}可用於先產生ERR陷阱,這可能會執行一些對偵錯有用的操作,然後終止腳本並顯示錯誤指示。

autoconf但文件中的情況並非如此。autoconf腳本依靠EXIT陷阱來清理運行期間創建的臨時檔案。大多數 shell(包括)將在呼叫陷阱之前bash根據命令中提供的值設定狀態。這可以允許陷阱檢測它是從錯誤還是正常終止中調用,並且還允許它確保在陷阱操作結束時正確設置退出狀態。exitEXITEXIT

然而,顯然有些外殼不合作。這是來自autoconf手動的:

某些 shell 腳本(例如由 產生的腳本autoconf)在退出前使用陷阱進行清理。如果最後一個 shell 指令以非零狀態退出,則陷阱也會以非零狀態退出,以便呼叫者可以知道發生了錯誤。

不幸的是,在某些 shell(例如 Solaris)中/bin/sh,退出陷阱會忽略 exit 指令的參數。在這些 shell 中,陷阱無法確定它是由普通退出呼叫還是由退出 1 呼叫AC_MSG_ERROR

解決方法是確保$?具有退出狀態exit命令被執行,因此當EXIT陷阱執行時它肯定會具有該值。事實上,正是這個AC_MSG_ERROR巨集插入了奇怪的程式碼,並帶有多餘的大括號。

答案2

據我所知,這樣做沒有任何目的,沒有什麼可以透過啟動子shell然後立即退出來直接實現。

像這樣的事情很可能是自動產生程式碼的副作用 - 在某些情況下,可能會在子 shell 中執行其他命令,而這些命令是有意義的exit 1。最終,透過允許產生程式碼插入一些在某些情況下沒有任何功能的語句,產生程式碼很有可能在某種程度上得到簡化,而每次產生「乾淨的程式碼」會更加複雜。要嘛是那個,要嘛是產生上述程式碼的程式碼寫得不好:)

自由使用{...}是另一個例子,它們中的大多數都是多餘的,但是編寫在每種情況下插入它們的程式碼更容易(也許在某些情況下您想要重定向區塊的輸出/輸入)而不是區分那些不需要的地方並省略它們。

答案3

(exit 1)是一種簡單的、可能是最簡單的獲取特定退出代碼的方法(當然,在 1 的特殊情況下,還有更簡單的方法)。但這不是本例的原因,因為沒有檢查退出代碼。

放入子 shell 的目的exit可能是不退出腳本(儘管使用 exit 來產生特定的退出代碼)。

相關內容