it-swarm-vi.com

Sự khác biệt giữa Nohup, disown và &

Sự khác biệt giữa

$ Nohup foo

$ foo &

$ foo & 
$ disown
600
lesmana

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ừ Shell tương tác (được kết nối với 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 đang chạy foo được tạo.
  • Quá trình này 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 SIGHUP, thì nó cũng sẽ gửi SIGHUP cho quy trình (điều này thường làm cho quá trình kết thúc).
  • Nếu không, Shell 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 đang chạy foo được tạo.
  • Quá trình kế thừa thiết bị xuất chuẩn/thiết bị xuất chuẩn từ Shell (vì vậy nó vẫn ghi vào thiết bị đầu cuối).
  • Quá trình về nguyên tắc cũng kế thừa stdin, nhưng ngay khi nó cố gắng đọ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 (trong đó n là số công việc).
    • Nó có thể được biế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 & trên đó (và nếu nó bị dừng do cố đọ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 SIGHUP, thì nó cũng sẽ gửi SIGHUP cho quy trình. Tùy thuộc vào Shell và có thể trên các tùy chọn được đặt cho Shell, khi kết thúc Shell, nó cũng sẽ gửi SIGHUP cho quy trình.

Bây giờ disown xóa 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 phụ ở trên không áp dụng nữa (bao gồm cả quy trình được gửi bở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.

Mặt khác, Nohup làm gì để phân 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 có 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 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 Nohup.out, vì vậy chương trình sẽ không thất bại khi 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 SIGHUP (vì vậy tên).

Lưu ý rằng Nohup does không xóa quy trình khỏi kiểm soát công việc của Shell và cũng không đặt nó vào nền (nhưng vì một foreground Nohup công việc ít nhiều vô dụng, bạn thường đặt nó vào nền bằng cách 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 Shell không chờ hoàn thành.
  • disown xóa quy trình khỏi kiểm soát công việc của Shell, nhưng nó vẫn để nó được kết nối với thiết bị đầu cuối. Một trong những kết quả là Shell sẽ không gửi cho nó một 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 khỏi 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ỳ SIGHUP nào được gửi. 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).
595
celtschk

Sử dụng & khiến chương trình chạy ở chế độ nền, vì vậy bạn sẽ nhận được Shell Prompt mới thay vì chặn cho đến khi chương trình kết thúc. Nohupdisown phần lớn không liên quan; chúng triệt tiêu tín hiệu SIGHUP (gác máy) để chương trình không tự động bị tắt khi đóng thiết bị đầu cuối điều khiển. Nohup thực hiện việc này khi công việc bắt đầu. Nếu bạn không Nohup một công việc khi nó bắt đầu, bạn có thể sử dụng disown để sửa đổi một công việc đang chạy; không có đối số, nó sửa đổi công việc hiện tại, đó là công việc vừa được làm nền

174
Michael Mrozek

Dưới đây là kinh nghiệm của tôi khi cố gắng chạy soffice trong nền, theo lệnh không kết thúc (ví dụ: tail). Trong ví dụ này tôi sẽ sử dụng sleep 100.

&

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Tôi xem soffice log/bằng cách nhấn Ctrl-C soffice dừng lại

Không .. &

#!/bin/bash
Nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Tôi không thấy soffice log/bằng cách nhấn Ctrl-C dừng lại

& từ chối

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100

Tôi xem soffice log/bằng cách nhấn Ctrl-C soffice dừng lại

setid .. &

#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Tôi xem soffice log/bằng cách nhấn Ctrl-C soffice KHÔNG DỪNG

Để tiết kiệm không gian:
[.__.] Nohup setsid ..: không hiển thị nhật ký/soffice KHÔNG DỪNG vào Ctrl-C
[.__.] Nohup với & disown ở cuối: không hiển thị nhật ký/soffice dừng trên Ctrl-C

9
Marinos An