nohup 指令:用法、nohup.out 與關閉終端機後繼續執行
想讓工作在關閉終端機或 SSH 連線中斷後繼續執行,就用 nohup 指令來執行。nohup 會讓指令忽略終端機關閉時送來的斷線訊號 (SIGHUP) 再執行。在 AlmaLinux 9 伺服器上同時啟動加了 nohup 的 sleep 和沒加的 sleep 並關閉終端機後,只有用 nohup 啟動的那個留下來繼續執行。
以下輸出是在 AlmaLinux 9.8 伺服器(root 帳號)和 Debian 12 伺服器(一般帳號)上執行的結果。以 sleep 代替長時間執行的工作,結束時只指定啟動時拿到的 PID。時間以 UTC 輸出。
1️⃣ nohup 指令用法
nohup 放在要執行的指令前面,並用指令結尾的 & 指定 背景執行。依 GNU 官方手冊,nohup 本身不會把指令送到背景,所以拿掉 & 的話,要等指令結束提示字元才會回來。
nohup sleep 300 &[1] 3431609
nohup: ignoring input and appending output to 'nohup.out'[1] 是工作編號,3431609 是啟動的程序的 PID。接著出現的訊息說明不會讀取鍵盤輸入,輸出會附加到 nohup.out 檔案。
剛啟動的工作的 PID 會留在 $! 裡,所以啟動後立刻用 [echo $!] 確認並記下來,查看狀態或結束時就直接用這個編號。
echo $!3431609關閉終端機時,shell 會收到斷線訊號,並把同樣的訊號送給它啟動的工作(依 Bash 官方手冊)。為了確認這個行為,在新的終端機中同時啟動了 [nohup sleep 300 &] 與沒有 nohup 的 [sleep 301 &]。
sleep 301 &[2] 3432892jobs -l[1]- 3432883 Running nohup sleep 300 &
[2]+ 3432892 Running sleep 301 &兩個工作都是 Running 時關閉終端機視窗,再從另一個 shell 用 ps 確認兩個 PID。
ps -p 3432883,3432892 -o pid,stat,etime,cmd PID STAT ELAPSED CMD
3432883 S 00:05 sleep 300只剩下用 nohup 啟動的 sleep 300,沒有 nohup 啟動的 sleep 301 在關閉終端機時一起結束了。
用 nohup 啟動的程序,就像開了勿擾模式的手機。
nohup 是 coreutils 套件裡的指令。已安裝的版本用 --version 的第一行確認。AlmaLinux 9.8 伺服器是 8.32,Debian 12 伺服器是 9.1。
nohup --version | head -1nohup (GNU coreutils) 8.32nohup --version | head -1nohup (GNU coreutils) 9.12️⃣ nohup.out 與輸出重新導向
沒有另外指定輸出位置時,nohup 會把指令的輸出附加到目前資料夾的 nohup.out。剛建立的 nohup.out 大小為 0,權限是只有建立者能讀寫的 -rw-------。
ls -l nohup.out-rw------- 1 root root 0 Oct 28 23:04 nohup.outGNU 官方手冊說明,不論 umask 設定為何,nohup 建立 nohup.out 時都只讓建立者能讀寫。如果無法寫入目前資料夾,就寫到家目錄的 $HOME/nohup.out,連那裡也無法寫入時就不執行指令。
用 nohup 執行有輸出的指令後,指令結束了輸出仍留在 nohup.out 中。
nohup sh -c 'echo start; sleep 2; echo end' &[1] 3431985
nohup: ignoring input and appending output to 'nohup.out'cat nohup.outstart
end
[1]+ Done nohup sh -c 'echo start; sleep 2; echo end'最後一行的 Done 是 shell 通知工作已結束。nohup.out 不會每次執行都重新建立,而是接在同一個檔案末尾繼續寫入,所以在同一個資料夾啟動多個工作時,輸出會混在一個檔案裡。
想讓每個工作的記錄分開,就用 > 指定輸出檔,再用 2>&1 把錯誤輸出也送到同一個檔案。
nohup sh -c 'echo start; sleep 300' > job.log 2>&1 &[1] 3432059cat job.lognohup: ignoring input
start加上 2>&1 後,終端機只顯示工作編號和 PID,nohup 的提示訊息 [nohup: ignoring input] 則記錄在記錄檔的第一行。
只加 > 而拿掉 2>&1 時,終端機會出現把錯誤輸出導向標準輸出檔案的提示。
nohup sleep 300 > job2.log &[2] 3432097
nohup: ignoring input and redirecting stderr to stdout不需要保留輸出的工作就送到 /dev/null。這時終端機也只顯示工作編號和 PID。
nohup sleep 300 > /dev/null 2>&1 &[3] 3432137四種執行方式的輸出去向和終端機顯示的訊息如下。
| 執行方式 | 輸出去向 | 終端機顯示的訊息 |
|---|---|---|
| nohup 指令 & | 目前資料夾的 nohup.out | nohup: ignoring input and appending output to 'nohup.out' |
| nohup 指令 > 檔案 & | 指定的檔案(含錯誤輸出) | nohup: ignoring input and redirecting stderr to stdout |
| nohup 指令 > 檔案 2>&1 & | 指定的檔案 | 無(提示訊息在檔案第一行) |
| nohup 指令 > /dev/null 2>&1 & | 丟棄 | 無 |
3️⃣ 確認與結束 nohup 程序
jobs 清單只顯示目前 shell 啟動的工作,所以關閉終端機再重新連線後,要用 ps -p 指定 PID 來確認 nohup 程序。還在同一個 shell 時,用 jobs -l 可以一起確認工作編號、PID 和狀態。
jobs -l[1]+ 3431609 Running nohup sleep 300 &在 ps -p 後面寫上 PID 並用 -o 選欄位,就只會顯示該程序那一行。STAT 的 S 是等待事件而睡眠的狀態,ELAPSED 是啟動後經過的時間。
ps -p 3431609 -o pid,stat,etime,cmd PID STAT ELAPSED CMD
3431609 S 00:03 sleep 300要結束時,在 kill 後面寫上 PID。
kill 3431609kill 沒有任何輸出,接著執行 jobs,該工作顯示為 Terminated 後就從清單消失。
jobs[1]+ Terminated nohup sleep 300用同一個 PID 再執行一次 ps,只顯示標題列,確認程序已經結束。
ps -p 3431609 -o pid,stat,etime,cmd PID STAT ELAPSED CMDnohup 只忽略斷線訊號,所以就算用 [kill -HUP] 直接送出同樣的訊號也不會結束。對用 nohup 啟動的 sleep 305 和沒有 nohup 啟動的 sleep 306 送出了 kill -HUP。
kill -HUP 3437119 3437128接著用 jobs -l 確認,只有 nohup 那個仍是 Running,sleep 306 以 Hangup 結束。
jobs -l[1]- 3437119 Running nohup sleep 305 &
[2]+ 3437128 Hangup sleep 306kill 不指定訊號時會送出 SIGTERM,所以用 nohup 啟動的工作也能用 [kill PID] 結束。
4️⃣ nohup 指令與 disown 比較、選項
🔲 nohup 與 disown 比較
disown 是用在已經啟動的工作上的 bash 內建指令,用來把沒有 nohup、以 & 啟動的工作,事後與終端機的斷線訊號分開。disown 不會把輸出導向 nohup.out,所以有輸出的工作要在啟動時用 > 檔案 先決定輸出位置。
依 Bash 官方手冊,不加選項使用 disown 時,該工作會從 jobs 清單移除;disown -h 則把工作留在清單中,只是不送斷線訊號給它。先啟動 sleep 302,再執行 disown。
sleep 302 &[1] 3433230disowndisown 沒有任何輸出,接著執行的 jobs -l 也是空的結果。
jobs -l接下來啟動 sleep 303,對工作編號 %1 執行 disown -h。
sleep 303 &[1] 3433343disown -h %1用 jobs -l 確認後,工作仍留在清單中。
jobs -l[1]+ 3433343 Running sleep 303 &再另外啟動一個不做任何處理的 sleep 304,關閉終端機後,從另一個 shell 確認三個 PID。
sleep 304 &[2] 3433474ps -p 3433230,3433343,3433474 -o pid,stat,etime,cmd PID STAT ELAPSED CMD
3433230 S 00:11 sleep 302
3433343 S 00:08 sleep 303用了 disown 與 disown -h 的兩個工作留了下來,只有沒做任何處理的 sleep 304 結束。四種方法比較如下。
| 方法 | 使用時機 | jobs 清單 | 關閉終端機後 | 輸出 |
|---|---|---|---|---|
| nohup 指令 & | 啟動時 | 保留 | 保留 | nohup.out 或指定的檔案 |
| 指令 & 之後 disown | 啟動後 | 省略 | 保留 | 不變 |
| 指令 & 之後 disown -h | 啟動後 | 保留 | 保留 | 不變 |
| 只有指令 & | — | 保留 | 已結束 | 不變 |
需要叫回工作畫面繼續輸入的工作,適合用 tmux 這類終端機多工器;啟動一次後只從檔案取得結果的工作,用 nohup 就夠了。
🔲 nohup 指令選項
📌 主要選項:本文實際執行的結果
| 選項 | 作用 | 本文看到的結果 | |
|---|---|---|---|
| --version | 顯示版本資訊後結束 | AlmaLinux 9.8 伺服器是 nohup (GNU coreutils) 8.32,Debian 12 伺服器是 nohup (GNU coreutils) 9.1 |
📎 其他選項:依官方手冊
| 選項 | 作用 | |
|---|---|---|
| --help | 顯示說明後結束 |
🔲 nohup 指令模擬器
在下方的模擬器中,可以用 nohup 啟動工作,用 🔌 按鈕關閉終端機再重新連線,親自確認哪些程序會留下來。
🔢 FAQ & 推薦內容
ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。