為什麼需要 nohup?
關閉終端時,Shell 會向其子進程發送 SIGHUP(掛起信號),預設動作為終止進程。守護進程 會忽略此信號,但一般前景/後台進程會退出。
nohup 原理
- 忽略
SIGHUP 信號。
- 若標準輸出/錯誤未重導向,自動寫入
nohup.out(目前目錄或 $HOME)。
- 若已重導向,則寫入指定檔案。
語法與用法
nohup COMMAND [ARG...] [&]
範例
# 後台執行並忽略 SIGHUP,輸出導向 nohup.out
nohup ./my_script.sh &
# 指定輸出檔案
nohup ./my_script.sh > my.log 2>&1 &
# 僅後台執行(不忽略 SIGHUP,關終端會死)
./my_script.sh &
nohup vs & 對照
| 特性 | nohup | & |
| 忽略 SIGHUP | 是 | 否 |
| 後台執行 | 需搭配 & | 是 |
| 關終端後存活 | 是(搭配 &) | 否(除非是守護進程) |
| 輸出處理 | 自動導向 nohup.out | 仍連接終端 |
退出碼說明
126:找到命令但無法執行(權限問題)。
127:nohup 本身錯誤或找不到命令。
- 其他:命令本身的退出碼。
實戰技巧
- 已經在前景執行的程式怎麼送後台並免疫 SIGHUP?
Ctrl+Z 暫停 → bg 送後台 → disown -h %1 移除 Shell 任務表關聯(不再收到 SIGHUP)。
- systemd 服務更優雅:長期運行服務請寫
.service 檔,交給 systemd 管理,支援自動重啟、日誌、依賴控制。
- screen/tmux:互動式長時間任務首選,可斷線重連。
常見誤區
直接點視窗關閉按鈕(而非 exit)會強制銷毀 Session,導致 nohup 進程同步收到 SIGHUP 而終止。正確流程:nohup cmd & → 看到 PID 輸出 → exit 正常登出。