Do `disown -h` và` nohup` hoạt động hiệu quả như nhau?


18

disown

  • làm cho trình bao không gửi SIGHUP đến công việc bị từ chối của nó khi trình bao kết thúc và

  • loại bỏ công việc bị từ chối khỏi kiểm soát công việc của vỏ.

Là lần đầu tiên kết quả của lần thứ hai? Nói cách khác, nếu một quy trình bắt đầu từ trình bao được loại bỏ khỏi kiểm soát công việc của trình bao bằng bất kỳ cách nào, thì trình bao không gửi SIGHUP đến quy trình khi trình bao kết thúc?

disown -h vẫn giữ một quá trình dưới sự kiểm soát công việc của một vỏ. Điều đó có nghĩa là disown -hlàm cho một quy trình vẫn nhận được SIGHUP được gửi từ trình bao, nhưng thiết lập hành động của SIGHUP theo quy trình để "bỏ qua"? Nghe có vẻ tương tự nohup.

$ sleep 123 & disown -h
[1] 26103
$ jobs
[1]+  Running                 sleep 123 &
$ fg 1
sleep 123
$ ^Z
[1]+  Stopped                 sleep 125
$ bg 1
[1]+ sleep 123 &
$ exit

$ ps aux | grep sleep
t        26103  0.0  0.0  14584   824 ?        S    15:19   0:00 sleep 123

Làm disown -hnohuplàm việc hiệu quả như nhau, nếu chúng ta bỏ qua sự khác biệt của họ trong việc sử dụng một thiết bị đầu cuối?

Cảm ơn.


Một điểm khác biệt không được thảo luận ở đây là nếu bạn không sử dụng nohup, bạn cần chuyển hướng stdin / stdout / stderr ra khỏi TTY (nếu vỏ ban đầu của bạn được kết nối với một). (OTOH, tôi thực sự xem xét rằng thực hành tốt hơn là dựa vào một mặc định mã hóa cứng như thế ./nohup.out).
Charles Duffy

Câu trả lời:


21

nohupdisown -hkhông hoàn toàn giống nhau

Với disown, một quy trình được xóa khỏi danh sách các công việc trong trình vỏ tương tác hiện tại. Chạy jobssau khi bắt đầu một quá trình nền và chạy disownsẽ không hiển thị quá trình đó như một công việc trong trình bao. Một công việc bị từ chối sẽ không nhận được HUPtừ vỏ khi nó thoát (nhưng xem ghi chú ở cuối).

Với disown -h, công việc không bị xóa khỏi danh sách các công việc, nhưng shell sẽ không gửi HUPtín hiệu cho nó nếu nó thoát (nhưng xem ghi chú ở cuối).

Các nohuptiện ích bỏ qua các HUPtín hiệu và bắt đầu các tiện ích nhất định. Tiện ích kế thừa mặt nạ tín hiệu từ nohupvà do đó cũng sẽ bỏ qua HUPtín hiệu. Khi shell kết thúc, quá trình này vẫn là một quá trình con của nohup(và nohupđược cấp lại cho init).

Sự khác biệt là quá trình bắt đầu với nohupbỏ qua HUPbất kể ai gửi tín hiệu. Các quá trình từ bỏ chỉ là không gửi một HUPtín hiệu bằng vỏ , nhưng vẫn có thể được gửi tín hiệu từ ví dụ kill -s HUP <pid>và sẽ không bỏ qua này.

Lưu ý rằng HUPchỉ được gửi đến các công việc của shell nếu

  • shell là shell đăng nhập và huponexittùy chọn shell được đặt, hoặc
  • Vỏ tự nhận HUPtín hiệu.

Các bit có liên quan từ bashhướng dẫn (nhấn mạnh của tôi):

TÍN HIỆU

[...]

Shell thoát theo mặc định khi nhận được aSIGHUP . Trước khi thoát, một vỏ tương tác gửi lại SIGHUPtất cả các công việc, đang chạy hoặc dừng. Các công việc đã dừng được gửi SIGCONTđể đảm bảo rằng họ nhận được SIGHUP. Để ngăn vỏ gửi tín hiệu đến một công việc cụ thể, nó cần được xóa khỏi bảng công việc có tích hợp disown(xem SHELL BUILTIN COMMANDSbên dưới) hoặc được đánh dấu để không nhận SIGHUP sử dụng disown -h.

Nếu huponexittùy chọn shell đã được đặt shopt, hãy bashgửi một SIGHUPđến tất cả các công việc khi thoát vỏ đăng nhập tương tác.

disown [-ar] [-h] [jobspec ... | pid ... ]

Không có tùy chọn, loại bỏ từng jobspectừ bảng công việc đang hoạt động. [...] Nếu -htùy chọn được đưa ra, mỗi cái jobspecsẽ không bị xóa khỏi bảng, nhưng được đánh dấu để nó SIGHUPkhông được gửi đến công việc nếu shell nhận được aSIGHUP . [...]

Liên quan:


Tôi nhận được bash: disown: nohup: no such jobvà tương tự cho sleep5từ disown nohup sleep 5 &. Ý của câu lệnh thứ hai từ câu cuối là gì?
Ruslan

@Ruslan Có, tôi đang thiếu một thứ &trong đó (và thứ tự nohupdisowncũng sai). Cảm ơn. Sẽ cập nhật ngay.
Kusalananda


@Tim Xin lỗi vì đã chỉnh sửa quá nhiều câu trả lời. Phải mất một lúc để có được đầu của tôi xung quanh nó. Tôi đã xong rồi.
Kusalananda

Cảm ơn. disownlàm cho một cái vỏ không được gửi SIGHUP cho một đứa trẻ bằng cách loại bỏ đứa trẻ khỏi danh sách công việc của cái vỏ. Làm thế nào để disown -hđạt được như vậy?
Tim

4

Họ khác nhau:

  • disown loại bỏ công việc khỏi bảng công việc đang hoạt động. Sau đó tiếp tục với công việc hiện tại. Với -h, bộ xử lý KHÔNG được gửi SIGHUP. Thay vào đó, nó sẽ chết đi với cái vỏ chứa nó, khi nó nhận được SIGHUP.

  • nohup bỏ qua HUP. Sau đó, bất cứ điều gì đã được chuyển đến thiết bị đầu cuối bằng cách đóng cửa bộ xử lý thay vào đó đi đến một tập tin nohup.out.

    nohup được xác định bởi POSIX trong khi từ chối thì không.


Ý bạn là gì, "chết với cái vỏ chứa nó"? Giết chết một quá trình cha mẹ không tự nó giết chết một đứa trẻ. Các chương trình có thiết bị đầu cuối bị đóng thường chết vì các lỗi liên quan đến nỗ lực tương tác với một tệp xử lý được đính kèm với PTY của thiết bị đầu cuối, nhưng nếu stdin / stdout / stderr được chuyển hướng ở nơi khác, điều đó sẽ không xảy ra.
Charles Duffy
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.