Trước tiên chúng ta hãy xem điều gì xảy ra nếu một chương trình được bắt đầu từ một vỏ tương tác (được kết nối với một thiết bị đầu cuối) mà không có &
(và không có bất kỳ sự chuyển hướng nào). Vì vậy, giả sử bạn vừa gõ foo
:
- Quá trình chạy
foo
được tạo ra.
- Quá trình kế thừa stdin, stdout và stderr từ shell. Do đó, nó cũng được kết nối với cùng một thiết bị đầu cuối.
- Nếu shell nhận được a
SIGHUP
, nó cũng sẽ gửi a SIGHUP
đến tiến trình (điều này thường làm cho quá trình kết thúc).
- Nếu không, vỏ chờ (bị chặn) cho đến khi quá trình kết thúc.
Bây giờ, hãy xem điều gì sẽ xảy ra nếu bạn đặt quá trình ở chế độ nền, nghĩa là, gõ foo &
:
- Quá trình chạy
foo
được tạo ra.
- Quá trình kế thừa stdout / stderr từ shell (vì vậy nó vẫn ghi vào terminal).
- Quá trình về nguyên tắc cũng kế thừa stdin, nhưng ngay khi nó cố đọc từ stdin, nó đã bị dừng lại.
- Nó được đưa vào danh sách các công việc nền mà shell quản lý, có nghĩa là đặc biệt:
- Nó được liệt kê với
jobs
và có thể được truy cập bằng cách sử dụng %n
( n
số công việc ở đâu).
- Nó có thể được chuyển thành một công việc tiền cảnh bằng cách sử dụng
fg
, trong trường hợp đó nó tiếp tục như thể bạn sẽ không sử dụng &
nó (và nếu nó bị dừng do cố gắng đọc từ đầu vào tiêu chuẩn, bây giờ nó có thể tiến hành đọc từ thiết bị đầu cuối).
- Nếu shell nhận được a
SIGHUP
, nó cũng sẽ gửi a SIGHUP
tới tiến trình. Tùy thuộc vào trình bao và có thể tùy chọn được đặt cho trình bao, khi kết thúc trình bao, nó cũng sẽ gửi một SIGHUP
quy trình.
Bây giờ disown
loại bỏ công việc khỏi danh sách công việc của shell, vì vậy tất cả các điểm con ở trên không áp dụng nữa (bao gồm cả quá trình được gửi SIGHUP
bởi shell). Tuy nhiên, lưu ý rằng nó vẫn được kết nối với thiết bị đầu cuối, vì vậy nếu thiết bị đầu cuối bị phá hủy (điều này có thể xảy ra nếu đó là một pty, giống như những thứ được tạo bởi xterm
hoặc ssh
, và chương trình điều khiển bị chấm dứt, bằng cách đóng xterm hoặc chấm dứt kết nối SSH ) , chương trình sẽ thất bại ngay khi nó cố đọc từ đầu vào tiêu chuẩn hoặc ghi vào đầu ra tiêu chuẩn.
nohup
Mặt khác, điều gì làm là tách hiệu quả quá trình khỏi thiết bị đầu cuối:
- Nó đóng đầu vào tiêu chuẩn (chương trình sẽ không thể đọc bất kỳ đầu vào nào, ngay cả khi nó được chạy ở nền trước. Nó không bị dừng, nhưng sẽ nhận được mã lỗi hoặc
EOF
).
- Nó chuyển hướng đầu ra tiêu chuẩn và lỗi tiêu chuẩn cho tập tin
nohup.out
, vì vậy chương trình sẽ không thể ghi vào đầu ra tiêu chuẩn nếu thiết bị đầu cuối bị lỗi, do đó, bất cứ điều gì quá trình ghi không bị mất.
- Nó ngăn quá trình nhận một
SIGHUP
(vì vậy tên).
Lưu ý rằng nohup
không phải loại bỏ quá trình này khỏi sự kiểm soát công việc của vỏ và cũng không đặt nó ở chế độ nền (nhưng vì một foreground nohup
công việc là nhiều hơn hoặc ít vô dụng, bạn sẽ thường đặt nó vào nền sử dụng &
). Ví dụ, không giống như disown
, shell vẫn sẽ cho bạn biết khi nào công việc nohup đã hoàn thành (tất nhiên trừ khi shell bị chấm dứt trước đó, tất nhiên).
Vì vậy, để tóm tắt:
&
đặt công việc ở chế độ nền, nghĩa là làm cho nó bị chặn khi cố đọc đầu vào và làm cho trình bao không chờ hoàn thành.
disown
loại bỏ quá trình khỏi kiểm soát công việc của shell, nhưng nó vẫn để nó kết nối với thiết bị đầu cuối. Một trong những kết quả là vỏ sẽ không gửi nó a SIGHUP
. Rõ ràng, nó chỉ có thể được áp dụng cho các công việc nền, bởi vì bạn không thể nhập nó khi một công việc nền trước đang chạy.
nohup
ngắt kết nối tiến trình từ thiết bị đầu cuối, chuyển hướng đầu ra của nó đến nohup.out
và bảo vệ nó khỏi SIGHUP
. Một trong những hiệu ứng (cách đặt tên) là quá trình sẽ không nhận được bất kỳ gửi nào SIGHUP
. Nó hoàn toàn độc lập với kiểm soát công việc và về nguyên tắc có thể được sử dụng cho các công việc tiền cảnh (mặc dù điều đó không hữu ích lắm).