Nohup

使用 & 和輸出重定向而不是 nohup 是否安全?

  • July 23, 2017

有很多關於 nohup 的堆棧交換答案,這裡有幾個供參考:

如果您已經使用 ‘&’ 分叉,什麼時候需要 ’nohup’?

為什麼使用“nohup &”而不是“exec &”

規範的答案似乎是,使用 nohup 可以防止程序在終端關閉時結束,所以像這樣的命令:

nohup mycommand >& mycommand_output.txt &

下次我登錄時仍然會執行,它會保存輸出,以便我以後檢查。

但是如果我保存了一些擊鍵:

mycommand >& mycommand_output.txt &

下次登錄時仍然在執行。

它與 nohup 不同,因為我可以用kill -HUP. 當我重新登錄時,ps -x說程序的 TTY 是 now ?,所以程序還沒有連接到終端。

為什麼當我退出 shell 時程序沒有停止?

如果我不使用 nohup,我可以安全地假設我的流程不會結束嗎?

萬一這很重要,我目前的環境涉及從 Ubuntu 機器通過 SSH 連接到 Debian 機器。

如果我不使用 nohup,我可以安全地假設我的流程不會結束嗎

不會。如果終端掛斷並且它有一個互動式 shell 作為會話負責人,shell 將獲得一個 SIGHUP 並將其重新發送到它尚未被拒絕的工作。

huponexit如果 shell 自願退出,如果該選項打開,它將向其作業發送 SIGHUP 。

如果 shell 自願退出並且擁有的作業被停止,bash 將使用 SIGTERM 殺死它們(不確定這是否是標準行為)。

如果 shell 自願退出並且有停止的不承認的作業,終端驅動程序將使用 SIGHUP 殺死它們(這絕對是標準規定的)。

所以你仍然可以在各種情況下被 SIGHUP 殺死。

也就是說,通過查看http://src.gnu-darwin.org/src/usr.bin/nohup/nohup.c.html上的 nohup 原始碼,它似乎在純 shell 中或多或少是可行的:

nohup_sh()
(
   set -e
   if [ -t 1]; then
       exec >> nohup.out || exec >> "$HOME/nohup.out"
   fi
   if [ -t 0 ]; then
       exec 0</dev/null
   fi
   if [ -t 2 ]; then
       exec 2>&1
   fi
   trap '' HUP #ignore SIGHUP (inheritable)
   set -m || : #to prevent SIGINT and SIGQUIT from being ignored
   #(probably not needed, but the nohup binary won't ignore them, unlike
   # & without set -m)

   command "$@" &
)

您可能不需要 之外的額外內容trap '' HUP,儘管如果該作業嘗試寫入斷開連接的終端(這是重定向阻止的),它將獲得 SIGPIPE。

為什麼當我退出 shell 時程序沒有停止?

可能是因為你告訴了shell disown。或者,您可能沒有使用互動式作業控制 shell 作為會話領導程序。

世界在 1980 年代確定的會話+程序組組合模型的工作方式如下:有一個會話負責人程序。這就是在終端掛斷時從終端線路規程中獲取掛斷信號的原因。預計會放大該信號,本身將信號發送到它產生的所有“工作”。互動式作業控制外殼將執行此操作;大多數其他程序不期望有會議負責人的職責,也不會。

nohup當會話領導者向它們發送掛斷信號時,使用使這些“作業”中的程序忽略掛斷信號。Usingdisown使會話領導者 shell 忘記了一項工作,因此它從一開始就不會向它發送掛斷信號。

如果我不使用 nohup,我可以安全地假設我的流程不會結束嗎?

不會。如果它們沒有被disowned,那麼會話領導者互動式作業控制 shell 程序將向它們發送掛斷信號。

此外:systemd 的人試圖實現與核心會話等效的使用者空間機制,但他們對此有點耳熟能詳,這在(某些)systemd 作業系統上引入了進一步的複雜性。在 systemd session hangup 而不是SIGHUP像核心的 line 規則那樣只發送給 session leader,它們錯誤地發送SIGTERM所有程序,錯誤地表示shutdown而不是hangup

SIGTERM在標準會話+程序組模型中,系統關閉時,所有程序當然會發生什麼;這會殺死所有程序,包括不承認的程序和忽略掛斷信號的程序。當然,它也會殺死你既沒有被disown編輯也沒有被編輯nohup的程序。

進一步閱讀

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