Sự khác biệt giữa nohup và ampersand


242

Cả hai nohup myprocess.out &hoặc myprocess.out &đặt my process.out để chạy trong nền. Sau khi tôi tắt thiết bị đầu cuối, quá trình vẫn đang chạy. Sự khác biệt giữa chúng là gì?


bạn đang sử dụng cái vỏ nào? hành vi khác nhau giữa các vỏ sò
shx2

1
bash. Và tôi biết tại sao bây giờ theo câu trả lời của @nemo.
Yarkee

@Yarkee nếu câu trả lời phù hợp với vấn đề của bạn, vui lòng đánh dấu câu hỏi là được chấp nhận (hộp kiểm bên dưới phiếu bầu của câu trả lời) để nó không bị treo lủng lẳng như chưa được trả lời. Bạn nên làm như vậy cho tất cả các câu hỏi của bạn :)
nemo

1
shutdownnên tránh như một thuật ngữ có nghĩa Linux cụ thể. và được thay thế bằng exit.
Patrizio Bertoni

Câu trả lời:


316

nohupbắt tín hiệu gác máy (xem man 7 signal) trong khi ký hiệu và không (ngoại trừ vỏ được xác nhận theo cách đó hoặc hoàn toàn không gửi SIGHUP).

Thông thường, khi chạy một lệnh sử dụng &và thoát khỏi shell sau đó, shell sẽ chấm dứt lệnh phụ với tín hiệu gác máy ( kill -SIGHUP <pid>). Điều này có thể được ngăn chặn bằng cách sử dụng nohup, vì nó bắt được tín hiệu và bỏ qua nó để nó không bao giờ đến được ứng dụng thực tế.

Trong trường hợp bạn đang sử dụng bash, bạn có thể sử dụng lệnh shopt | grep huponđể tìm hiểu xem trình bao của bạn có gửi SIGHUP tới các tiến trình con của nó hay không. Nếu nó bị tắt, các tiến trình sẽ không bị chấm dứt, vì dường như đó là trường hợp của bạn. Thông tin thêm về cách bash chấm dứt các ứng dụng có thể được tìm thấy ở đây .

Có những trường hợp nohupkhông hoạt động, ví dụ như khi quá trình bạn bắt đầu kết nối lại SIGHUPtín hiệu, vì đó là trường hợp ở đây .


Có thể đáng lưu ý rằng chỉ &làm cho các tiểu ban không nhận được một số tín hiệu (ví dụ SIGINT). nohupvề cơ bản thêm SIGHUPvào danh sách các tín hiệu không được truyền đi.
studgeek

46

myprocess.out &sẽ chạy quá trình trong nền bằng cách sử dụng một lớp con. Nếu shell hiện tại bị chấm dứt (nói bằng cách đăng xuất), tất cả các lớp con cũng bị chấm dứt do đó quá trình nền cũng sẽ bị chấm dứt. Lệnh nohup bỏ qua HUPtín hiệu và do đó ngay cả khi lớp vỏ hiện tại bị chấm dứt, lớp con và myprocess.outsẽ tiếp tục chạy trong nền. Một sự khác biệt nữa là &một mình không chuyển hướng thiết bị xuất chuẩn / thiết bị xuất chuẩn, vì vậy nếu có bất kỳ đầu ra hoặc lỗi nào, chúng sẽ được hiển thị trên thiết bị đầu cuối. mặt khác, chuyển hướng thiết bị xuất chuẩn / thiết bị xuất chuẩn sang nohup.outhoặc $HOME/nohup.out.


6
Tôi chạy myprocess.out &và thoát khỏi vỏ. Tuy nhiên, khi tôi sử dụng ps aux | grep myprocess.outtrong shell khác, tôi vẫn có thể tìm thấy "my process.out". Nó có nghĩa là hơn quá trình vẫn đang chạy, không bị chấm dứt.
Yarkee

1
@amit_g Khi giết shell cha bằng kill -9sẽ không có SIGHUP vì điều này sẽ yêu cầu shell cha phải xử lý SIGKILL, điều này không thể.
nemo

2
Kiểm tra shopt | grep hupon như đã đề cập trong câu trả lời khác.
amit_g

31

Hầu hết thời gian chúng tôi đăng nhập vào máy chủ từ xa bằng ssh. Nếu bạn bắt đầu một tập lệnh shell và bạn đăng xuất thì quá trình sẽ bị hủy. Nohup giúp tiếp tục chạy tập lệnh ở chế độ nền ngay cả sau khi bạn đăng xuất khỏi shell.

Nohup command name &
eg: nohup sh script.sh &

Nohup bắt các tín hiệu HUP. Nohup không đặt công việc tự động trong nền. Chúng ta cần nói rõ rằng sử dụng &


Cảm ơn. Không mong đợi câu trả lời của bạn nhưng thực tế là nó ở đây rất tuyệt. Nó trả lời câu hỏi tôi không hỏi: D
Vaibhav Kaushal

26

Sử dụng ký hiệu (&) sẽ chạy lệnh trong một tiến trình con (con đến phiên bash hiện tại). Tuy nhiên, khi bạn thoát phiên, tất cả các tiến trình con sẽ bị giết.

sử dụng nohup + ampersand (&) sẽ làm điều tương tự, ngoại trừ khi phiên kết thúc, cha mẹ của quá trình con sẽ được đổi thành "1", đó là quá trình "init", do đó bảo vệ trẻ khỏi bị giết.


7

Sửa lỗi cho tôi nếu tôi sai

  nohup myprocess.out &

nohup bắt tín hiệu gác máy, có nghĩa là nó sẽ gửi một quá trình khi đóng thiết bị đầu cuối.

 myprocess.out &

Quá trình có thể chạy nhưng sẽ dừng lại khi thiết bị đầu cuối được đóng lại.

nohup myprocess.out

Quá trình có thể chạy ngay cả thiết bị đầu cuối đã đóng, nhưng bạn có thể dừng quá trình bằng cách nhấn ctrl+ ztrong thiết bị đầu cuối. Crt+ zkhông hoạt động nếu &có.


2

Lệnh nohup là một tiện ích che dấu tín hiệu và bắt tín hiệu gác máy. Trường hợp như ampersand không bắt được tín hiệu gác máy. Shell sẽ chấm dứt lệnh phụ với tín hiệu gác máy khi chạy lệnh bằng cách sử dụng & và thoát khỏi shell. Điều này có thể được ngăn chặn bằng cách sử dụng nohup, vì nó bắt được tín hiệu. Lệnh Nohup chấp nhận tín hiệu gác máy có thể được gửi đến một tiến trình bởi kernel và chặn chúng. Lệnh Nohup hữu ích khi người dùng muốn bắt đầu chạy ứng dụng dài ra hoặc đóng cửa sổ trong đó quá trình được bắt đầu. Một trong những hành động này thường nhắc kernel treo trên ứng dụng, nhưng trình bao bọc nohup sẽ cho phép quá trình tiếp tục. Sử dụng ký hiệu và sẽ chạy lệnh trong một tiến trình con và con này của phiên bash hiện tại. Khi bạn thoát phiên, tất cả các quá trình con của quá trình đó sẽ bị giết. Dấu và liên quan đến kiểm soát công việc cho vỏ hoạt động. Điều này rất hữu ích để chạy một quá trình trong một phiên trong nền.


0

Có nhiều trường hợp khi sự khác biệt nhỏ giữa các môi trường có thể cắn bạn. Đây là một trong đó tôi đã chạy gần đây. Sự khác biệt giữa hai lệnh này là gì?

1 ~ $ nohup myprocess.out &
2 ~ $ myprocess.out &

Câu trả lời giống như bình thường - nó phụ thuộc.

nohup bắt tín hiệu gác máy trong khi ampersand thì không.

Tín hiệu gác máy là gì?

SIGHUP - hangup được phát hiện trên thiết bị đầu cuối kiểm soát hoặc tử vong của quá trình kiểm soát (giá trị: 1).

Thông thường, khi chạy lệnh bằng cách sử dụng & thoát khỏi shell sau đó, shell sẽ chấm dứt lệnh phụ với tín hiệu gác máy (như kill -SIGHUP $ PID). Điều này có thể được ngăn chặn bằng cách sử dụng nohup, vì nó bắt được tín hiệu và bỏ qua nó để nó không bao giờ đến được ứng dụng thực tế.

Tốt, nhưng như trong trường hợp này luôn có "buts". Không có sự khác biệt giữa các phương thức khởi chạy này khi shell được cấu hình theo cách mà nó hoàn toàn không gửi SIGHUP.

Trong trường hợp bạn đang sử dụng bash, bạn có thể sử dụng lệnh được chỉ định bên dưới để tìm hiểu xem trình bao của bạn có gửi SIGHUP tới các tiến trình con của nó hay không:

~ $ shopt | grep hupon

Và hơn nữa - có những trường hợp nohup không hoạt động. Ví dụ: khi quá trình bạn bắt đầu kết nối lại tín hiệu NOHUP (nó được thực hiện bên trong, ở cấp mã ứng dụng).

Trong trường hợp được mô tả, thiếu khác biệt với tôi khi bên trong tập lệnh khởi chạy dịch vụ tùy chỉnh, có một lệnh gọi đến tập lệnh thứ hai để thiết lập và khởi chạy ứng dụng phù hợp mà không cần lệnh nohup.

Trên một môi trường Linux, mọi thứ đều hoạt động trơn tru, ở lần thứ hai, ứng dụng thoát ngay khi tập lệnh thứ hai thoát ra (phát hiện trường hợp đó, tất nhiên tôi phải mất nhiều thời gian hơn thì bạn có thể nghĩ: bị mắc kẹt :).

Sau khi thêm nohup làm phương thức khởi chạy vào tập lệnh thứ hai, ứng dụng sẽ tiếp tục chạy ngay cả khi tập lệnh sẽ thoát và hành vi này trở nên nhất quán trên cả hai môi trường.

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.