如何在 Linux 中使用 nohup 命令

已發表: 2022-06-25
顯示 bash 提示符的 Linux 筆記本電腦
fatmawati achmad zaenuri/Shutterstock.com

Linux nohup命令可以讓重要進程在啟動它們的終端窗口關閉時繼續運行。 我們將向您展示如何在當今的 Linux 上使用這個古老的命令。

HUP 和 SIGHUP

Linux 的祖先 Unix 是在 PC 發明之前創建的。 計算機是大型、昂貴的設備。 人們通過串行線路在同一建築物內本地或通過慢速調製解調器連接與他們進行遠程交互。 最初,他們在逐漸被啞終端取代的電傳打字機上輸入指令。

他們被稱為啞巴,因為處理能力在你連接的計算機上,而不是你正在打字的終端上。 這些程序是在計算機上運行的——它可能在哪裡——而不是在你桌面上的設備上。

如果發生什麼中斷了您的終端和計算機之間的連接,計算機會檢測到線路掉線並向您正在運行的程序發送HUP掛斷信號。 程序收到信號後停止執行。

如何殺死 Linux 上的桌面應用程序或後台進程
相關如何在 Linux 上終止桌面應用程序或後台進程

該功能在今天的 Linux 中仍然存在。 在您的 PC 上,終端窗口是物理終端的模擬。 如果您正在運行從該終端窗口啟動的進程並關閉該窗口,則SIGHUP信號將發送到程序,以便它們被告知HUP並知道它們應該終止。

發生了級聯效應。 如果進程啟動了任何子進程,則 SIGHUP 也會向下傳遞給它們,以便它們知道應該終止。

nohup命令啟動子進程,但拒絕將SIGHUP信號傳遞給它們。 這聽起來像是一個問題,但它實際上是一個有用的功能。

nohup 命令

如果你想讓一個進程在啟動它的終端窗口關閉的情況下繼續,你需要一種攔截SIGHUP的方法,這樣程序就永遠不會收到它。 (實際上,終端窗口不會啟動進程,它們是由終端窗口內的 shell 會話啟動的。)該問題的簡單而優雅的解決方案是在 shell 會話和程序之間放置另一個進程,並擁有它中間層程序從不傳遞SIGHUP信號。

這就是nohup所做的。 它為您啟動程序,使它們成為nohup的子進程,而不是 shell 的子進程。 因為它們不是 shell 的子進程,所以它們不會直接從 shell 接收SIGHUP 。 如果nohup不將SIGHUP傳遞給它的孩子,程序將根本不會收到SIGHUP

例如,當您需要讓運行完成的長時間運行的進程時,這很有用。 如果您不小心關閉了終端窗口及其外殼,您也將終止該進程。 使用nohup啟動進程將進程與nohup信號隔離開來。 如果您通過 SSH 在計算機上遠程工作,並且您不希望敏感進程在遠程連接失敗時終止,則可以使用nohup在遠程計算機上啟動該進程。

使用 nohup

我們創建了一個程序,它沒有做任何有用的事情,但它會運行並運行直到它被終止。 它每三秒將時間打印到終端窗口。 它被稱為“長過程”的long-proc

 ./long-proc 

運行終端窗口的 long-proc 程序

如果這是一個做了一些有用的程序並且我們希望它在終端窗口和 shell 關閉的情況下繼續運行,我們將使用nohup啟動它。

 nohup ./long-proc 

從 nohup 啟動 long-proc 程序

該進程與stdinstdout分離,因此它既不能接收任何輸入也不能寫入終端窗口。 此外,由於它仍在運行,您不會返回到命令提示符。 nohup所做的只是使進程不受終端關閉的影響。 它不會將進程變成後台任務。

您現在是否必須重新啟動才能終止該過程? 否。要停止您尚未作為後台進程啟動的nohup進程,請按 Ctrl+C 組合鍵。

使用 Ctrl+C 停止 long-proc 進程

該程序的輸出已為我們捕獲在一個名為“nohup.out”的文件中。 我們可以用更少的東西來審查它。

 少 nohup.out 

在 less 中打開 nohup.out 文件

通常發送到終端窗口的任何內容都會被捕獲在文件中。 nohup的後續運行將附加到現有的“nohup.out”文件中。

long-proc 的輸出寫入 nohup.out 文件,以 less 顯示

運行該進程的一種更有用的方法是使用nohup啟動它,以便它能夠承受終端窗口的關閉,同時使其成為後台任務。 為此,我們在命令行末尾添加一個&符號。

 nohup ./long-proc & 

使用 nohup 啟動 long-proc 程序並使其成為後台任務

您需要再次按“Enter”以返回命令提示符。 我們被告知進程的作業編號是 1——括號“ [] ”中的數字——並且進程 ID 是 13115。

我們可以使用其中任何一個來終止進程。 “Ctrl+C”現在不起作用,因為程序與終端窗口或 shell 沒有任何關聯。

如果您忘記了作業編號,您可以使用jobs命令列出已從該終端窗口啟動的後台任務。

 工作

列出從終端窗口啟動的後台任務

要終止我們的任務,我們可以使用kill命令和作業編號,前面有一個百分號“ % ”,如下所示:

 殺死 %1

如果您關閉了終端窗口,您需要找到進程 ID 並將其與kill命令一起使用。 pgrep命令將查找與您提供的搜索線索匹配的進程的進程 ID。 我們將搜索進程名稱。

 pgrep 長過程

按名稱查找進程的進程 ID

現在我們可以使用進程 ID 來終止進程。

 殺死13115 

使用 kill 命令和進程 ID 終止進程

下次您按“Enter”時,系統會通知您該過程已終止。

現在讓我們看看什麼不會終止進程。 我們將重新啟動它,然後關閉終端窗口。

 nohup ./long-proc 

在進程運行時關閉終端窗口

如果我們打開一個新的終端窗口並使用pgrep搜索我們的進程,我們會看到它仍在運行。 關閉啟動進程的終端窗口沒有任何效果。

 pgrep 長過程

使用 pgrep 按名稱搜索進程

可以將多個命令傳遞給nohup ,但通常最好單獨啟動它們。 它使將它們作為後台作業進行操作變得更加容易。 這些命令不會同時運行,它們將一個接一個地執行。 執行不是並發的,它是順序的。 要讓它們同時運行,您需要單獨啟動它們。

話雖如此,要一次啟動多個進程,請使用nohup啟動 Bash shell 並將-c (命令)選項與命令字符串一起使用。 使用單引號“ ' ”將命令列表括起來,使用雙與號“ && ”分隔命令。

 nohup bash -c 'ls /bin && ls /sbin' 

使用 nohup 啟動兩個進程

如果您使用less查看“nohup.out”文件,您將看到第一個進程的輸出,然後是第二個進程的輸出。

 少 nohup.out 

在 less 中打開 nohup.out 文件

兩個命令的輸出都被捕獲在“nohup.out”文件中。 它沒有交織在一起,第二個進程的輸出僅在第一個進程終止後才開始。

less 中 nohup.out 文件的內容

如果您想使用您自己的文件而不是“nohup.out”,您可以將命令重定向到您選擇的文件中。

 nohup bash -c 'ls /bin && ls /sbin' > myfile.txt 

將進程的輸出重定向到用戶提供的文件

請注意,消息不再說“將輸出附加到 nohupo.out”,而是說“將 stderr 重定向到 stdout”,我們正在將 stdout 重定向到“myfile.txt”文件。

我們可以用 less 查看“myfile.txt”文件。

 少 myfile.txt 

和以前一樣,它包含兩個命令的輸出。


有趣的是,公用事業的歷史有時會讓人覺得它與現代無關。 nohup命令就是其中之一。 為處理串行線路上的斷開而創建的東西對於今天在功能非常強大的機器上的 Linux 用戶仍然有用。

相關:你應該知道的 37 個重要的 Linux 命令