Hướng dẫn dùng nohup (no hangup) chạy lệnh/script tiếp tục sau khi đóng terminal/SSH – thiết yếu cho tác vụ chạy dài (backup, restore DB, training ML...).
Cú pháp cơ bản
# nohup command [args] &
- nohup: Bỏ qua signal
SIGHUP(gửi khi terminal đóng). - &: Chạy background (job control shell).
- Output stdout/stderr mặc định ghi vào
nohup.out(thư mục hiện tại).
Ví dụ: Backup MySQL lớn qua SSH
# ssh user@server
# nohup mysqldump -u user -p'pass' large_db > large_db.sql 2>&1 &
[1] 3999
nohup: appending output to 'nohup.out'
2>&1: Gộp stderr vào stdout → cùng ghi vào nohup.out.3999: PID của tiến trình.
Kiểm tra tiến trình
# ps -ef | grep 3999
# jobs -l # Xem job shell hiện tại
# tail -f nohup.out # Theo dõi output real-time
Khi tiến trình kết thúc
[1]+ Done nohup mysqldump ...
Kiểm tra nohup.out để xem lỗi (nếu có).
Tùy chỉnh file output
# nohup command > mylog.log 2>&1 &
# nohup command >> append.log 2>&1 &
So sánh: nohup vs disown vs screen/tmux vs systemd
| Công cụ | Phù hợp | Ưu điểm | Nhược điểm |
|---|---|---|---|
| nohup | Command/script đơn lẻ, ngắn hạn | Đơn giản, có sẵn, giữ output | Không tương tác lại được, khó quản lý nhiều job |
| disown -h %1 | Đã chạy, muốn tách khỏi shell | Không cần khởi động lại | Chỉ tác động job hiện tại shell |
| screen | Phiên tương tác, nhiều cửa sổ | Attach/detach, scrollback, multi-window | Cần cài, nhẹ hơn tmux |
| tmux | Phiên tương tác chuyên nghiệp | Pane, session persist, scriptable, plugin | Học curve cao hơn screen |
| systemd service | Service chạy dài, production | Auto-start, restart, logging, dependency, security | Cần cấu hình unit file, quyền root |
Best Practice cho Server Production
- Tác vụ một lần (backup, migrate):
nohuphoặcscreen/tmux. - Tác vụ lặp lại (cron, worker): systemd timer/service hoặc cron.
- Luôn redirect output:
> logfile 2>&1. - Dùng PID file + lock: Tránh chạy trùng.
- Thông báo khi xong: Thêm
; echo "Done" | mail -s "Job done" admin@domain.comvào cuối command.
Ví dụ hoàn chỉnh an toàn
nohup bash -c 'mysqldump -u$USER -p"$PASS" db > backup_$(date +%F).sql 2>&1; echo "Backup done" | mail -s "DB Backup" admin@example.com' > backup.log 2>&1 &