Shell

nohup、disown 和 & 之間的區別

  • October 26, 2021

之間有什麼區別

$ nohup foo

$ foo &

$ foo & 
$ disown

讓我們首先看看如果一個程序從一個互動式外殼(連接到終端)啟動而沒有&(也沒有任何重定向)會發生什麼。所以讓我們假設你剛剛輸入foo

  • 正在執行的程序foo被創建。
  • 該程序從 shell 繼承 stdin、stdout 和 stderr。因此它也連接到同一個終端。
  • 如果 shell 收到 a SIGHUP,它也會向SIGHUP程序發送 a (這通常會導致程序終止)。
  • 否則,shell 會等待(被阻塞),直到程序終止或停止。

現在,讓我們看看如果將程序置於後台會發生什麼,即鍵入foo &

  • 正在執行的程序foo被創建。

  • 該程序從 shell 繼承 stdout/stderr(因此它仍然寫入終端)。

  • 該程序原則上也繼承了標準輸入,但是一旦它嘗試從標準輸入中讀取,它就會停止。

  • 它被放入 shell 管理的後台作業列表中,這尤其意味著:

    • 它與(作業編號在哪裡)一起列出jobs並且可以訪問。%n``n
    • 可以使用 將其轉換為前台作業fg,在這種情況下,它會繼續執行,就好像您不會使用&它一樣(如果它由於嘗試從標準輸入讀取而停止,它現在可以繼續從終端讀取)。
    • 如果 shell 收到 a SIGHUP,它也會向SIGHUP程序發送 a 。根據 shell 和可能為 shell 設置的選項,當終止 shell 時,它也會向SIGHUP程序發送一個。

現在disown從 shell 的作業列表中刪除作業,因此上面的所有子點不再適用(包括SIGHUP由 shell 發送的程序)。但是請注意,它仍然連接到終端,所以如果終端被破壞(如果它是一個 pty,例如由xtermor創建的那些ssh,並且通過關閉 xterm 或終止SSH連接來終止控製程序,則可能發生這種情況) ,程序一旦嘗試從標準輸入讀取或寫入標準輸出就會失敗。

nohup另一方面,有效地將程序與終端分離:

  • 它關閉標準輸入(程序將無法讀取任何輸入,即使它在前台執行。它不會停止,但會收到錯誤程式碼或EOF)。
  • 它將標準輸出和標準錯誤重定向到文件nohup.out,因此如果終端失敗,程序寫入標準輸出不會失敗,因此無論程序寫入什麼都不會失去。
  • 它阻止程序接收一個SIGHUP(因此名稱)。

請注意,nohup不會從 shell 的作業控制中刪除程序,也不會將其置於後台(但由於前台nohup作業或多或少無用,您通常會使用 將其置於後台&)。例如,與 with 不同disown,shell 仍然會告訴您 nohup 作業何時完成(當然,除非 shell 之前終止)。

所以總結一下:

  • &將作業置於後台,也就是說,使其阻止嘗試讀取輸入,並使 shell 不等待其完成。
  • disown從 shell 的作業控制中刪除該程序,但仍將其連接到終端。結果之一是外殼不會向它發送SIGHUP. 顯然,它只能應用於後台作業,因為在前台作業執行時無法進入。
  • nohup斷開程序與終端的連接,將其輸出重定向nohup.outSIGHUP. 效果之一(命名)是該程序不會收到任何 sent SIGHUP。它完全獨立於作業控制,原則上也可以用於前台作業(儘管這不是很有用)。

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