Câu trả lời:
Những gì tốt hơn, một con cá hoặc một chiếc xe đạp? nohup
và exec
làm những việc khác nhau.
exec
thay thế vỏ bằng một chương trình khác. Sử dụng exec
trong một công việc nền đơn giản không hữu ích: exec myprogram; more stuff
thay thế shell bằng myprogram
và do đó không chạy more stuff
, không giống như myprogram; more stuff
chạy more stuff
khi myprogram
chấm dứt; nhưng exec myprogram & more stuff
bắt đầu myprogram
trong nền và sau đó chạy more stuff
, giống như myprogram & more stuff
.
nohup
chạy chương trình cụ thể với tín hiệu SIGHUP bị bỏ qua. Khi một thiết bị đầu cuối được đóng, hạt nhân sẽ gửi SIGHUP đến quá trình kiểm soát trong thiết bị đầu cuối đó (tức là hệ vỏ). Shell lần lượt gửi SIGHUP cho tất cả các công việc đang chạy trong nền. Điều hành một công việc với việc nohup
ngăn chặn nó bị giết theo cách này nếu thiết bị đầu cuối bị chết (điều này xảy ra, ví dụ nếu bạn đã đăng nhập từ xa và kết nối bị rớt hoặc nếu bạn đóng trình giả lập thiết bị đầu cuối).
nohup
cũng chuyển hướng đầu ra của chương trình vào tập tin nohup.out
. Điều này tránh chương trình bị chết vì không thể ghi vào đầu ra hoặc đầu ra lỗi. Lưu ý rằng nohup
không chuyển hướng đầu vào. Để ngắt kết nối hoàn toàn một chương trình khỏi thiết bị đầu cuối nơi bạn khởi chạy nó, hãy sử dụng
nohup myprogram </dev/null >myprogram.log 2>&1 &
exec firefox
, shell không còn chạy nữa: nó đã được thay thế bởi firefox
. Bạn có thể nghĩ đến exec
việc kết hợp thoát khỏi một chương trình và bắt đầu một chương trình mới, nhưng vẫn giữ nguyên ID quá trình. Thiết bị đầu cuối tiếp tục chạy vì không có gì bảo nó dừng lại. Khi bạn thoát khỏi Firefox sau đó, firefox
quá trình sẽ chấm dứt. Thiết bị đầu cuối thông báo rằng quá trình con của nó đã thoát và do đó nó thoát ra lần lượt.
exec &
=> thực thi một quy trình như một quy trình nền để bạn có thể tiếp tục sử dụng cùng một thiết bị đầu cuối cho các công việc khác.
nohup
=> tránh tất cả SIGHUP (tín hiệu kết thúc) và tiếp tục thực thi ngay cả khi thiết bị đầu cuối của bạn bị đóng.
exec
quá trình chết khi SIGHUP
nhận được, nhưng nohup
quá trình tiếp tục.
exec
thay thế quá trình đang chạy, nhưng điều đó dường như không xảy ra khi bạn sử dụng &
để làm nền cho lệnh exec'd. Không trong bash cũng không zsh.
exec smth &
giống như (exec smth) &
, đó không phải là điều đang xảy ra sao?
(exec smth) &
. Nhưng tôi không mong đợi nó giống như vậy - tôi sẽ coi đó là lỗi cú pháp, làm thế nào bạn có thể thực hiện một quy trình (thay thế chính mình) và sau đó làm nền cho quy trình thực thi? Bạn không còn ở đó để làm điều đó nữa.
Shell được xây dựng trong lệnh exec <command>
thay thế shell bằng <command>
, không có quy trình mới, không có PID mới được tạo. Sau khi hoàn thành <command>
bình thường thiết bị đầu cuối của bạn sẽ đóng cửa. Bằng cách chạy nó trong nền trước tiên, một lớp con được tạo ra, sau đó tương tự ngay lập tức được thay thế bằng <command>
.
Các nohup <command>
lệnh sẽ chạy <command>
nhưng immume để hangups (giết -s 1) vì vậy nó sẽ không được chấm dứt khi vỏ, các thiết bị đầu cuối từ đó nó đã được bắt đầu là, được đóng lại. Bằng cách chạy nó trong nền trước tiên, một lớp con được tạo và lệnh chạy trong nền, đưa bạn trở lại dấu nhắc.
Trong kịch bản, hiệu ứng ngay lập tức ít nhiều giống nhau, <command>
được bắt đầu bởi tập lệnh của bạn và tập lệnh sẽ tiếp tục mà không cần chờ <command>
để bắt đầu, gửi đầu ra hoặc hoàn thành.
script.sh &
hoặc exec script.sh &
. Trong cả hai trường hợp, lệnh được thực thi trong một tiến trình con, nó không thay thế quá trình gọi, xem: paste.alacon.org/44474 (quá lâu để sao chép nó ở đây trong một chú thích Bình luận). Tôi đang làm gì sai?
Bạn không thể so sánh nohup
với exec
. Khi bạn chạy một tệp thực thi với nohup
, quá trình sẽ không bị hủy khi bạn đăng xuất (phiên ssh); thường nohup
được sử dụng nice
để chạy các quy trình có mức độ ưu tiên thấp hơn. Theo HUP
quy ước, tín hiệu là cách một thiết bị đầu cuối cảnh báo các quá trình đăng xuất phụ thuộc