Tại sao nên sử dụng và nohup


67

Tôi biết rằng, nohuplà một nhị phân, nó có thể đạt được từ bất kỳ shell nào. Nhưng tích exechợp có lẽ tồn tại trong mọi vỏ.

Có một lý do để thích một trong số họ, cho người kia?

Câu trả lời:


113

Những gì tốt hơn, một con cá hoặc một chiếc xe đạp? nohupexeclàm những việc khác nhau.

execthay thế vỏ bằng một chương trình khác. Sử dụng exectrong một công việc nền đơn giản không hữu ích: exec myprogram; more stuffthay thế shell bằng myprogramvà do đó không chạy more stuff, không giống như myprogram; more stuffchạy more stuffkhi myprogramchấm dứt; nhưng exec myprogram & more stuffbắt đầu myprogramtrong nền và sau đó chạy more stuff, giống như myprogram & more stuff.

nohupchạ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 nohupngă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).

nohupcũ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 nohupkhô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 &

27
một chiếc xe đạp> một con cá
Chris Jaynes

6
Tôi có ý kiến ​​khác. Cá rõ ràng là một phương pháp vận chuyển ưu việt nếu nó có thể được thực hiện.
NGƯỜI DÙNG NÀY CẦN GIÚP

6
@THISUSERNEEDSHELP Nhưng một chiếc xe đạp là thực phẩm tốt hơn, chắc chắn?
Gilles 'SO- đừng trở nên xấu xa'

3
@GypsyCosmonaut Sau khi bạn chạy exec firefox, shell không còn chạy nữa: nó đã được thay thế bởi firefox. Bạn có thể nghĩ đến execviệ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 đó, firefoxquá 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.
Gilles 'SO- ngừng trở nên xấu xa'

5
Cho một người đàn ông một con cá và bạn cho anh ta ăn trong một ngày. Đưa cho một người đàn ông một chiếc xe đạp và anh ta có thể cưỡi nó đến siêu thị và mua cá suốt đời.
David

18

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.

execquá trình chết khi SIGHUPnhận được, nhưng nohupquá trình tiếp tục.


1
Câu trả lời này có vẻ đúng. Như các câu trả lời khác ở trên nói, thông thường execthay 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.
Dan Pritts

@DanPritts Ý bạn là gì với nó không xảy ra? Một quy trình con nền được bắt đầu và sau đó được thay thế, exec smth &giống như (exec smth) &, đó không phải là điều đang xảy ra sao?
phk

1
Ý tôi là nó không được thực thi theo nghĩa mà bạn thường nghĩ đến (thay thế lớp vỏ đang chạy hiện tại) - nó chỉ được chạy như một quá trình nền. Tôi đoán nó có thể giống như (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.
Dan Pritts

2

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.


Tôi cũng không chắc chắn về những gì thực hiện. Ý tôi là, tôi hiểu những gì nó phải làm nhưng tôi chỉ có thể thấy một sự khác biệt nhỏ giữa việc làm 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?
Stéphane

2

Bạn không thể so sánh nohupvớ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 HUPquy ướ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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.