Lệnh nohup: cách dùng, nohup.out và giữ tiến trình chạy tiếp khi đóng terminal

Môi trường thử nghiệmHọ RHELAlmaLinux 9.8coreutils 8.32Tài khoản rootDebian 12 · coreutils 9.1 tài khoản thườngKiểm tra ngày 2026-11-05
Vẫn chạy tiếp dù đóng terminal

Để công việc vẫn chạy tiếp khi bạn đóng terminal hoặc mất kết nối SSH, hãy chạy nó bằng lệnh nohup. nohup chạy lệnh trong trạng thái bỏ qua tín hiệu ngắt kết nối (SIGHUP) được gửi đến khi terminal đóng. Khi chạy cùng lúc một sleep có nohup và một sleep không có nohup trên máy chủ AlmaLinux 9 rồi đóng terminal, chỉ tiến trình chạy bằng nohup còn lại và tiếp tục chạy.

Kết quả bên dưới được chạy trên máy chủ AlmaLinux 9.8 (tài khoản root) và máy chủ Debian 12 (tài khoản thường). Thay cho công việc chạy lâu, sleep được dùng, và khi dừng chỉ chỉ định PID nhận được lúc khởi chạy. Thời gian được in theo UTC.

1️⃣ Cách dùng lệnh nohup

  • ↪️ Dấu & ở cuối lệnh và chuyện gì xảy ra khi đóng terminal

nohup được đặt trước lệnh cần chạy, và dấu & ở cuối lệnh chỉ định chạy nền. Theo tài liệu chính thức của GNU, bản thân nohup không đưa lệnh xuống chạy nền, nên nếu bỏ & thì dấu nhắc lệnh chỉ quay lại khi lệnh chạy xong.

nohup sleep 300 &
[1] 3431609
nohup: ignoring input and appending output to 'nohup.out'

[1] là số hiệu tác vụ, còn 3431609 là PID của tiến trình vừa chạy. Thông báo xuất hiện tiếp theo cho biết tiến trình không nhận đầu vào từ bàn phím và đầu ra sẽ được ghi nối vào tệp nohup.out.

PID của tác vụ vừa chạy được giữ trong $!, vì vậy hãy kiểm tra bằng [echo $!] ngay sau khi chạy và ghi lại; khi xem trạng thái hay dừng tác vụ, bạn dùng đúng số đó.

echo $!
3431609

Khi đóng terminal, shell nhận tín hiệu ngắt kết nối và gửi cùng tín hiệu đó đến các tác vụ mà nó đã chạy (theo tài liệu chính thức của Bash). Để kiểm chứng điều này, trong một terminal mới đã chạy cùng lúc [nohup sleep 300 &] và, không có nohup, [sleep 301 &].

sleep 301 &
[2] 3432892
jobs -l
[1]- 3432883 Running                 nohup sleep 300 &
[2]+ 3432892 Running                 sleep 301 &

Khi cả hai tác vụ đang ở trạng thái Running, cửa sổ terminal được đóng lại, rồi hai PID được kiểm tra bằng ps từ một shell khác.

ps -p 3432883,3432892 -o pid,stat,etime,cmd
    PID STAT     ELAPSED CMD
3432883 S          00:05 sleep 300

Chỉ còn sleep 300 chạy bằng nohup; sleep 301 chạy không có nohup đã kết thúc cùng lúc với việc đóng terminal.

Tiến trình chạy bằng nohup giống như chiếc điện thoại đang bật chế độ Không làm phiền.

nohup là lệnh thuộc gói coreutils. Phiên bản đã cài được xem ở dòng đầu tiên của --version. Máy chủ AlmaLinux 9.8 là 8.32, máy chủ Debian 12 là 9.1.

nohup --version | head -1
nohup (GNU coreutils) 8.32
nohup --version | head -1
nohup (GNU coreutils) 9.1

2️⃣ nohup.out và chuyển hướng đầu ra

  • ↪️ Chỉ định tệp log và /dev/null

Nếu bạn không chỉ định đầu ra đi đâu, nohup ghi nối đầu ra của lệnh vào nohup.out trong thư mục hiện tại. nohup.out vừa được tạo có kích thước 0 và quyền -rw-------, chỉ người dùng đã tạo mới đọc và ghi được.

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

Tài liệu chính thức của GNU giải thích rằng nohup tạo nohup.out sao cho chỉ người dùng đã tạo mới đọc và ghi được, bất kể thiết lập umask. Nếu không ghi được vào thư mục hiện tại, nohup ghi vào $HOME/nohup.out trong thư mục home, và nếu cả ở đó cũng không ghi được thì không chạy lệnh.

Khi chạy bằng nohup một lệnh có đầu ra, đầu ra vẫn còn trong nohup.out sau khi lệnh kết thúc.

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 ở dòng cuối là thông báo của shell rằng tác vụ đã xong. nohup.out không được tạo mới mỗi lần chạy mà được ghi nối vào cuối cùng một tệp, nên nếu chạy nhiều tác vụ từ cùng một thư mục, đầu ra sẽ lẫn vào một tệp.

Để tách log cho từng tác vụ, hãy chỉ định tệp đầu ra bằng > và gửi cả đầu ra lỗi vào cùng tệp đó bằng 2>&1.

nohup sh -c 'echo start; sleep 300' > job.log 2>&1 &
[1] 3432059
cat job.log
nohup: ignoring input
start

Khi thêm cả 2>&1, terminal chỉ hiện số hiệu tác vụ và PID, còn thông báo của nohup [nohup: ignoring input] được ghi ở dòng đầu của tệp log.

Nếu chỉ thêm > mà bỏ 2>&1, terminal hiện thông báo rằng đầu ra lỗi được chuyển sang tệp của đầu ra chuẩn.

nohup sleep 300 > job2.log &
[2] 3432097
nohup: ignoring input and redirecting stderr to stdout

Đầu ra của các tác vụ không cần giữ lại thì gửi vào /dev/null. Trường hợp này terminal cũng chỉ hiện số hiệu tác vụ và PID.

nohup sleep 300 > /dev/null 2>&1 &
[3] 3432137

Bảng dưới đây cho thấy đầu ra đã đi đâu và thông báo nào hiện ra trên terminal với bốn cách chạy.

Cách chạyĐầu ra đi đâuThông báo trên terminal
nohup lệnh &nohup.out trong thư mục hiện tạinohup: ignoring input and appending output to 'nohup.out'
nohup lệnh > tệp &Tệp đã chỉ định (gồm cả đầu ra lỗi)nohup: ignoring input and redirecting stderr to stdout
nohup lệnh > tệp 2>&1 &Tệp đã chỉ địnhKhông có (thông báo nằm ở dòng đầu tệp)
nohup lệnh > /dev/null 2>&1 &Bỏ điKhông có

3️⃣ Kiểm tra và dừng tiến trình nohup

  • ↪️ jobs, ps, kill

Danh sách jobs chỉ hiện các tác vụ chạy từ shell hiện tại, nên sau khi đóng terminal và kết nối lại, hãy kiểm tra tiến trình nohup bằng ps -p với PID. Khi vẫn còn ở cùng shell, jobs -l hiện số hiệu tác vụ, PID và trạng thái cùng lúc.

jobs -l
[1]+ 3431609 Running                 nohup sleep 300 &

Nếu ghi PID sau ps -p và chọn cột bằng -o, chỉ dòng của tiến trình đó hiện ra. S trong STAT là trạng thái ngủ chờ sự kiện, còn ELAPSED là thời gian đã trôi qua kể từ khi bắt đầu.

ps -p 3431609 -o pid,stat,etime,cmd
    PID STAT     ELAPSED CMD
3431609 S          00:03 sleep 300

Để dừng, hãy dùng kill kèm PID phía sau.

kill 3431609

kill không in ra gì, và khi chạy jobs tiếp theo, tác vụ đó hiện là Terminated rồi biến khỏi danh sách.

jobs
[1]+  Terminated              nohup sleep 300

Chạy lại ps với cùng PID thì chỉ hiện dòng tiêu đề, xác nhận rằng tiến trình đã kết thúc.

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

nohup chỉ bỏ qua tín hiệu ngắt kết nối, nên dù gửi trực tiếp cùng tín hiệu đó bằng [kill -HUP] thì tiến trình cũng không kết thúc. kill -HUP đã được gửi đến sleep 305 chạy bằng nohup và sleep 306 chạy không có nohup.

kill -HUP 3437119 3437128

Kiểm tra tiếp bằng jobs -l thì chỉ tác vụ nohup còn Running, còn sleep 306 đã kết thúc với Hangup.

jobs -l
[1]- 3437119 Running                 nohup sleep 305 &
[2]+ 3437128 Hangup                  sleep 306

Nếu không chỉ định tín hiệu cho kill, nó gửi SIGTERM, nên tác vụ chạy bằng nohup cũng kết thúc bằng [kill PID].

4️⃣ So sánh lệnh nohup với disown và các tùy chọn

  • ↪️ disown -h, khi nào chọn tmux, và tóm tắt tùy chọn

🔲 So sánh nohup và disown

disown là lệnh tích hợp của bash dùng cho các tác vụ đã chạy: dùng khi muốn tách về sau một tác vụ chạy bằng & mà không có nohup khỏi tín hiệu ngắt kết nối của terminal. disown không chuyển đầu ra sang nohup.out, nên với tác vụ có đầu ra, hãy chỉ định nơi nhận đầu ra bằng > tệp ngay khi chạy.

Theo tài liệu chính thức của Bash, dùng disown không kèm tùy chọn thì tác vụ bị đưa ra khỏi danh sách jobs, còn disown -h giữ tác vụ trong danh sách và chỉ không gửi tín hiệu ngắt kết nối đến nó. Trước tiên chạy sleep 302 rồi chạy disown.

sleep 302 &
[1] 3433230
disown

disown không in ra gì, và jobs -l chạy ngay sau đó cũng trả về kết quả trống.

jobs -l

Tiếp theo chạy sleep 303 và chạy disown -h cho tác vụ số %1.

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

Kiểm tra bằng jobs -l thì tác vụ vẫn còn trong danh sách.

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

Thêm một sleep 304 nữa không xử lý gì, đóng terminal rồi kiểm tra ba PID từ một shell khác.

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

Hai tác vụ dùng disown và disown -h vẫn còn, chỉ sleep 304 không xử lý gì là kết thúc. So sánh bốn cách như sau.

CáchKhi dùngDanh sách jobsSau khi đóng terminalĐầu ra
nohup lệnh &Khi chạyCònCònnohup.out hoặc tệp đã chỉ định
lệnh & rồi disownSau khi chạyĐược bỏ quaCònKhông đổi
lệnh & rồi disown -hSau khi chạyCònCònKhông đổi
Chỉ lệnh &—CònĐã kết thúcKhông đổi

Với công việc cần gọi lại màn hình phiên làm việc để gõ tiếp, bộ ghép kênh terminal như tmux là phù hợp; còn công việc chạy một lần và chỉ nhận kết quả qua tệp thì nohup là đủ.

🔲 Tùy chọn của lệnh nohup

📌 Tùy chọn chính: kết quả chạy trong bài này

Tùy chọnChức năngKết quả trong bài này
--versionIn thông tin phiên bản rồi thoátMáy chủ AlmaLinux 9.8: nohup (GNU coreutils) 8.32, máy chủ Debian 12: nohup (GNU coreutils) 9.1

📎 Tùy chọn khác: theo tài liệu hướng dẫn chính thức

Tùy chọnChức năng
--helpIn trợ giúp rồi thoát

🔲 Trình mô phỏng lệnh nohup

Trong trình mô phỏng bên dưới, bạn có thể chạy tác vụ bằng nohup, đóng terminal và kết nối lại bằng chip 🔌, rồi tự xem tiến trình nào còn lại.

Trình mô phỏng lệnh nohupcoreutils 8.32
[root@server work]#
Chỉ chạy trong trình duyệt và không khởi chạy tiến trình thật. Thời gian sleep trôi theo đồng hồ thật, và ↑↓ gọi lại các lệnh đã gõ trước đó.

🔢 FAQ & nội dung đề xuất

Theo tài liệu chính thức của GNU, nohup thoát với 125 nếu bản thân nohup thất bại, 126 nếu tìm thấy lệnh nhưng không chạy được, và 127 nếu không tìm thấy lệnh. Trên máy chủ AlmaLinux 9, chỉ gõ nohup mà không có lệnh cho 125, ./job.sh không có quyền thực thi cho 126, và lệnh không tồn tại nosuchcmd cho 127.

nohup không đổi giá trị nice, nên hãy dùng nice cùng với nó như [nohup nice -n 10 sleep 307 &]. Kiểm tra sleep chạy theo cách này bằng ps thì cột NI là 10, còn STAT là SN có chữ N biểu thị mức ưu tiên thấp.

Lệnh nohup chỉ có hai tùy chọn là [--help] và [--version]. Theo tài liệu chính thức của GNU, tùy chọn được ghi trước lệnh cần chạy.

ℹ️ Thông báo tiếp thị liên kết
Nội dung trên trang này có chứa liên kết affiliate (tiếp thị liên kết). Khi khách truy cập mua sản phẩm hoặc dịch vụ qua các liên kết này, trang sẽ nhận hoa hồng từ bên bán. Trong quá trình đó, số tiền người mua phải trả (sẽ giảm khi có chương trình khuyến mãi ↓) không hề tăng lên. Giá, khuyến mãi và tình trạng hàng được đăng theo thời điểm viết bài và có thể khác với thực tế, vì vậy hãy kiểm tra lại lần cuối với bên bán trước khi mua. Việc chọn và đánh giá sản phẩm dựa trên tiêu chí riêng của trang; việc có nhận hoa hồng hay không không ảnh hưởng đến thứ tự giới thiệu hay nội dung đánh giá.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Prove your humanity: 10   +   5   =