nohup 指令:用法、nohup.out 與關閉終端機後繼續執行

測試環境RHEL 系列AlmaLinux 9.8coreutils 8.32root 帳號Debian 12 · coreutils 9.1 一般帳號2026-11-05 確認
程序 · 工作排程指令nohup位置/usr/bin/nohup
關閉終端機也會繼續執行

想讓工作在關閉終端機或 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] 3432892
jobs -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 -1
nohup (GNU coreutils) 8.32
nohup --version | head -1
nohup (GNU coreutils) 9.1

2️⃣ nohup.out 與輸出重新導向

  • ↪️ 指定記錄檔與 /dev/null

沒有另外指定輸出位置時,nohup 會把指令的輸出附加到目前資料夾的 nohup.out。剛建立的 nohup.out 大小為 0,權限是只有建立者能讀寫的 -rw-------。

ls -l nohup.out
-rw------- 1 root root 0 Oct 28 23:04 nohup.out

GNU 官方手冊說明,不論 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.out
start
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] 3432059
cat job.log
nohup: 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.outnohup: 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, ps, kill

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 3431609

kill 沒有任何輸出,接著執行 jobs,該工作顯示為 Terminated 後就從清單消失。

jobs
[1]+  Terminated              nohup sleep 300

用同一個 PID 再執行一次 ps,只顯示標題列,確認程序已經結束。

ps -p 3431609 -o pid,stat,etime,cmd
    PID STAT     ELAPSED CMD

nohup 只忽略斷線訊號,所以就算用 [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 306

kill 不指定訊號時會送出 SIGTERM,所以用 nohup 啟動的工作也能用 [kill PID] 結束。

4️⃣ nohup 指令與 disown 比較、選項

  • ↪️ disown -h 與選擇 tmux 的標準、選項整理

🔲 nohup 與 disown 比較

disown 是用在已經啟動的工作上的 bash 內建指令,用來把沒有 nohup、以 & 啟動的工作,事後與終端機的斷線訊號分開。disown 不會把輸出導向 nohup.out,所以有輸出的工作要在啟動時用 > 檔案 先決定輸出位置。

依 Bash 官方手冊,不加選項使用 disown 時,該工作會從 jobs 清單移除;disown -h 則把工作留在清單中,只是不送斷線訊號給它。先啟動 sleep 302,再執行 disown。

sleep 302 &
[1] 3433230
disown

disown 沒有任何輸出,接著執行的 jobs -l 也是空的結果。

jobs -l

接下來啟動 sleep 303,對工作編號 %1 執行 disown -h。

sleep 303 &
[1] 3433343
disown -h %1

用 jobs -l 確認後,工作仍留在清單中。

jobs -l
[1]+ 3433343 Running                 sleep 303 &

再另外啟動一個不做任何處理的 sleep 304,關閉終端機後,從另一個 shell 確認三個 PID。

sleep 304 &
[2] 3433474
ps -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 啟動工作,用 🔌 按鈕關閉終端機再重新連線,親自確認哪些程序會留下來。

nohup 指令模擬器coreutils 8.32
[root@server work]#
只在瀏覽器裡運作,不會啟動真正的程序。sleep 的時間依實際時鐘流逝,用 ↑↓ 可以叫回之前輸入的指令。

🔢 FAQ & 推薦內容

依 GNU 官方手冊,nohup 本身失敗時以 125 結束,找到指令但無法執行時以 126 結束,找不到指令時以 127 結束。在 AlmaLinux 9 伺服器上只輸入 nohup 而沒有指令時為 125,沒有執行權限的 ./job.sh 為 126,不存在的指令 nosuchcmd 為 127。

nohup 不會改變 nice 值,所以要像 [nohup nice -n 10 sleep 307 &] 這樣搭配 nice 使用。用 ps 確認這樣啟動的 sleep,NI 欄是 10,STAT 是帶有表示低優先順序的 N 的 SN。

nohup 指令的選項只有 [--help] 和 [--version] 兩個。依 GNU 官方手冊,選項要寫在要執行的指令前面。

ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Prove your humanity: 8   +   10   =