如何在 Linux 中使用 nohup 命令
已發表: 2022-06-25 Linux nohup
命令可以讓重要進程在啟動它們的終端窗口關閉時繼續運行。 我們將向您展示如何在當今的 Linux 上使用這個古老的命令。
HUP 和 SIGHUP
Linux 的祖先 Unix 是在 PC 發明之前創建的。 計算機是大型、昂貴的設備。 人們通過串行線路在同一建築物內本地或通過慢速調製解調器連接與他們進行遠程交互。 最初,他們在逐漸被啞終端取代的電傳打字機上輸入指令。
他們被稱為啞巴,因為處理能力在你連接的計算機上,而不是你正在打字的終端上。 這些程序是在計算機上運行的——它可能在哪裡——而不是在你桌面上的設備上。
如果發生什麼中斷了您的終端和計算機之間的連接,計算機會檢測到線路掉線並向您正在運行的程序發送HUP
或掛斷信號。 程序收到信號後停止執行。
該功能在今天的 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
如果這是一個做了一些有用的程序並且我們希望它在終端窗口和 shell 關閉的情況下繼續運行,我們將使用nohup
啟動它。
nohup ./long-proc
該進程與stdin
和stdout
分離,因此它既不能接收任何輸入也不能寫入終端窗口。 此外,由於它仍在運行,您不會返回到命令提示符。 nohup
所做的只是使進程不受終端關閉的影響。 它不會將進程變成後台任務。
您現在是否必須重新啟動才能終止該過程? 否。要停止您尚未作為後台進程啟動的nohup
進程,請按 Ctrl+C 組合鍵。
該程序的輸出已為我們捕獲在一個名為“nohup.out”的文件中。 我們可以用更少的東西來審查它。
少 nohup.out
通常發送到終端窗口的任何內容都會被捕獲在文件中。 nohup
的後續運行將附加到現有的“nohup.out”文件中。
運行該進程的一種更有用的方法是使用nohup
啟動它,以便它能夠承受終端窗口的關閉,同時使其成為後台任務。 為此,我們在命令行末尾添加一個&
符號。
nohup ./long-proc &
您需要再次按“Enter”以返回命令提示符。 我們被告知進程的作業編號是 1——括號“ []
”中的數字——並且進程 ID 是 13115。
我們可以使用其中任何一個來終止進程。 “Ctrl+C”現在不起作用,因為程序與終端窗口或 shell 沒有任何關聯。
如果您忘記了作業編號,您可以使用jobs
命令列出已從該終端窗口啟動的後台任務。
工作
要終止我們的任務,我們可以使用kill
命令和作業編號,前面有一個百分號“ %
”,如下所示:
殺死 %1
如果您關閉了終端窗口,您需要找到進程 ID 並將其與kill
命令一起使用。 pgrep
命令將查找與您提供的搜索線索匹配的進程的進程 ID。 我們將搜索進程名稱。
pgrep 長過程
現在我們可以使用進程 ID 來終止進程。
殺死13115
下次您按“Enter”時,系統會通知您該過程已終止。
現在讓我們看看什麼不會終止進程。 我們將重新啟動它,然後關閉終端窗口。
nohup ./long-proc
如果我們打開一個新的終端窗口並使用pgrep
搜索我們的進程,我們會看到它仍在運行。 關閉啟動進程的終端窗口沒有任何效果。
pgrep 長過程
可以將多個命令傳遞給nohup
,但通常最好單獨啟動它們。 它使將它們作為後台作業進行操作變得更加容易。 這些命令不會同時運行,它們將一個接一個地執行。 執行不是並發的,它是順序的。 要讓它們同時運行,您需要單獨啟動它們。
話雖如此,要一次啟動多個進程,請使用nohup
啟動 Bash shell 並將-c
(命令)選項與命令字符串一起使用。 使用單引號“ '
”將命令列表括起來,使用雙與號“ &&
”分隔命令。
nohup bash -c 'ls /bin && ls /sbin'
如果您使用less
查看“nohup.out”文件,您將看到第一個進程的輸出,然後是第二個進程的輸出。
少 nohup.out
兩個命令的輸出都被捕獲在“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 命令