SSH 斷開、終端關閉、系統超時導致長時間任務中斷是運維常見痛點。本文系統梳理 **五大後台穩健運行方案**,按「臨時命令、已啟動補救、服務化長期運行」三類場景分類,原理清晰、命令可直接套用,徹底解決「一關窗口任務就掛」的問題。
SIGHUP 給前台進程組 → 進程默認退出。nohup command > output.log 2>&1 &
# 輸出重定向到 nohup.out(默認)或指定文件
# & 置入後台
# ps -ef | grep command 可見進程 PPID 為 1 (systemd/init)
setsid command > output.log 2>&1 &
# 進程成為會話首進程,PPID=1,不屬於原終端進程組
# 自然免疫 SIGHUP
( command & )
# 圓括號創建子 Shell,& 置入後台
# 子 Shell 結束後進程被 init 收養,PPID=1
# jobs 不可見,ps 可見
場景:命令已跑起來,忘加 nohup/&,不想重跑。
# 1. Ctrl+Z 掛起當前前台任務
^Z
[1]+ Stopped command
# 2. bg %1 放入後台繼續運行
bg %1
[1]+ command &
# 3. disown -h %1 從作業表移除並標記忽略 HUP
disown -h %1
# 4. 驗證
jobs # 列表中消失
ps -ef | grep command # 進程仍在,PPID=1
disown 變體:disown -ah(所有作業)、disown -rh(運行中作業)。
適用場景:Web 服務、定時任務、監控代理、任何需開機自啟、崩潰自動重啟、日誌集中管理的進程。
# /etc/systemd/system/myapp.service
[Unit]
Description=My Long Running App
After=network.target
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/start.sh
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now myapp
systemctl status myapp
journalctl -u myapp -f
| 場景 | 推薦方案 | 備選 |
|---|---|---|
| 臨時跑個腳本、備份、同步 | nohup / setsid | 子 Shell & |
| 已跑起來的前台任務不想中斷 | Ctrl+Z → bg → disown -h | - |
| 長期服務、開機自啟、生產環境 | systemd 服務 | Supervisor / PM2 |
| 需要交互式輸入/輸出 | tmux / screen | reptyr 接管現有進程 |
**臨時用 nohup/setsid,補救用 disown,長期上 systemd**。理解 SIGHUP/進程組/會話機制,靈活選擇工具,讓後台任務真正做到「關窗不死、斷網不斷、崩了自愈」。