nohup 讓程序在背景持續執行
在 Linux 系統管理與開發過程中,我們經常需要執行一些耗時較長或需要持續運行的任務,例如資料備份、日誌監控或長期運行的腳本。當我們透過 SSH 連線到伺服器時,如果直接關閉終端機視窗,該連線會中斷,導致正在執行的程序隨之被殺死(SIGHUP 訊號)。
為了解決這個問題,nohup(No Hang UP)指令應運而生。它能夠讓程序忽略掛斷訊號,確保即使 SSH 連線斷開,程序依然能在背景中持續運行。本文將深入解析 nohup 的運作原理、實際用法以及常見的使用情境。
nohup 的運作原理
nohup 的核心功能是讓執行的程序忽略 SIGHUP(Signal Hangup)訊號。當終端機關閉時,系統會向所有相關程序發送 SIGHUP 訊號,預設行為是終止程序。nohup 透過捕獲並忽略這個訊號,確保程序存活。
此外,nohup 還會自動處理標準輸出(stdout)和標準錯誤(stderr):
- 若標準輸出未重新導向,
nohup會自動將輸出內容寫入目前目錄下的nohup.out檔案。 - 若標準錯誤也未重新導向,它會與標準輸出合併,同樣寫入
nohup.out。 - 若
nohup.out無法建立(例如權限不足),輸出則會被丟棄。
基本語法與實際範例
nohup 的語法非常簡單,通常與其他背景執行指令 & 搭配使用。
1. 基本用法:忽略掛斷訊號
假設我們有一個名為 long_task.sh 的腳本,內容為無限迴圈並每秒輸出時間:
#!/bin/bash
while true; do
echo "Current time: $(date)"
sleep 1
done
賦予執行權限後,我們使用 nohup 執行它:
chmod +x long_task.sh
nohup ./long_task.sh &
輸出結果範例:
[1] 12345
nohup: ignoring input and appending output to 'nohup.out'
這裡的 [1] 12345 表示作業系統分配給該背景工作的編號為 1,程序 ID (PID) 為 12345。關鍵訊息 nohup: ignoring input and appending output to 'nohup.out' 告訴我們輸出已被重導向至 nohup.out。
2. 自訂輸出檔案
預設的 nohup.out 可能會因為多個程序同時執行而混淆。我們可以使用 > 或 >> 將輸出重導向至自訂檔案。
nohup ./long_task.sh > my_task.log 2>&1 &
> my_task.log:將標準輸出重導向至my_task.log。2>&1:將標準錯誤(stderr)重導向至標準輸出(stdout)的位置,確保錯誤訊息也會被記錄。&:讓程序在背景執行。
此時,檢查 my_task.log 即可看到持續輸出的時間戳記,而不會產生 nohup.out。
3. 結合 screen 或 tmux 的替代方案
雖然 nohup 方便,但它無法提供互動式終端介面。若需要與背景程序互動(例如查看即時日誌或輸入指令),建議使用 tmux 或 screen。但若僅需靜態背景運行,nohup 是最佳選擇。
常見問題與注意事項
1. nohup.out 檔案過大問題
由於 nohup 會持續將輸出追加到檔案中,若程序產生大量日誌,nohup.out 可能會迅速佔滿磁碟空間。
解決方案:
- 定期清理: 使用
cron定時清空或壓縮該檔案。 - 重導向至 /dev/null: 若不需要任何輸出,可將輸出丟棄:
nohup ./long_task.sh > /dev/null 2>&1 &
2. 如何正確終止 nohup 程序?
由於 nohup 程序已脫離終端機,無法用 Ctrl+C 終止。必須使用 kill 指令配合 PID。
步驟:
- 找出 PID:
ps aux | grep long_task.sh輸出範例:
user 12345 0.0 0.1 12340 3456 pts/0 S 10:00 0:00 ./long_task.sh - 終止程序:
kill 12345若程序未響應,可強制終止:
kill -9 12345
小結
nohup 是 Linux 系統管理員與開發者不可或缺的工具,特別適合用於自動化腳本、後台服務啟動或長時間運行的任務。透過簡單地將 nohup 與 & 結合,即可輕鬆讓程序在斷線後繼續運行。
然而,使用者應注意輸出檔案的管理與程序監控,避免磁碟空間耗盡或遺失重要程序。對於需要高度互動性的場景,建議搭配 tmux 或 screen 使用,以獲得更靈活的控制體驗。掌握 nohup 的正確用法,將大幅提升您在 Linux 環境下的工作效率與系統穩定性。