Có gì khác biệt giữa việc chạy một chương trình như một daemon và đưa nó vào nền với '&'?


Câu trả lời:


31

Cách truyền thống của daemonizing là:

fork()
setsid()
close(0) /* and /dev/null as fd 0, 1 and 2 */
close(1)
close(2)
fork()

Điều này đảm bảo rằng quy trình không còn nằm trong cùng nhóm quy trình với thiết bị đầu cuối và do đó sẽ không bị giết cùng với nó. Chuyển hướng IO là làm cho đầu ra không xuất hiện trên thiết bị đầu cuối.


5
Vì vậy, nếu một thiết bị đầu cuối sinh ra một quá trình nền (&) bị đóng, quá trình nền cũng sẽ chấm dứt?
dùng1561108

9
Quá trình sẽ nhận được SIGHUP khi thiết bị đầu cuối thoát, trình xử lý mặc định cho tín hiệu đó là chấm dứt quá trình.
Dennis Kaarsemaker

12
Vui lòng thêm &phần giải thích cho câu trả lời của bạn. Nó dường như là không đầy đủ .. nếu bạn kiểm tra câu hỏi ban đầu.
mtk

1
Đó là bởi vì chạy mọi thứ trong nền với & không làm cho quá trình làm bất cứ điều gì đặc biệt :)
Dennis Kaarsemaker

33

Đối với một daemon, những gì bạn muốn là một quá trình không có ràng buộc với bất cứ điều gì. Ít nhất, bạn muốn nó ở trong phiên riêng của nó, không được gắn vào thiết bị đầu cuối, không có bất kỳ mô tả tệp nào được kế thừa từ cha mẹ mở cho bất cứ điều gì, không có cha mẹ chăm sóc cho bạn (trừ init) có hiện tại thư mục /để không ngăn chặn ...

Để tách khỏi một thiết bị đầu cuối, bạn tạo một phiên mới, tuy nhiên, để tạo một phiên, bạn không phải là người lãnh đạo nhóm (hoặc phiên), vì vậy tốt nhất là nên rẽ nhánh một quy trình mới. Giả sử cha mẹ thoát ra, điều đó cũng có nghĩa là quá trình đó sẽ không còn cha mẹ nữa và sẽ được áp dụng bởi init. Sau đó, đóng tất cả các bộ mô tả tệp có thể, bạn chdir("/")(người ta không thể đóng thư mục làm việc hiện tại để giải phóng tài nguyên đó như cho bộ mô tả tệp, làm cho /các thư mục làm việc hiện tại ít nhất không ngăn được các thư mục không đếm được).

Bởi vì quy trình đó là một nhà lãnh đạo phiên, có một rủi ro là nếu nó mở một thiết bị đầu cuối, nó sẽ trở thành quy trình kiểm soát của thiết bị đầu cuối đó. Ngã ba lần thứ hai đảm bảo nó không xảy ra.

Mặt khác, &, trong các vỏ tương tác, tạo ra một nhóm quy trình mới (để không nằm trong nhóm quy trình tiền cảnh của thiết bị đầu cuối) và trong các vỏ không tương tác, tạo ra một quy trình và bỏ qua SIGINT trong đó. Nó không tách rời khỏi thiết bị đầu cuối, không đóng mô tả tệp (mặc dù một số shell sẽ mở lại stdin thành /dev/null) ...


sử dụng cho chdir ("/") là gì? để đóng mô tả tập tin?
Timothy Leung

@TimothyLeung, xem chỉnh sửa.
Stéphane Chazelas

8

Sự khác biệt giữa việc chạy một chương trình / quy trình như một daemon và chuyển nó xuống nền bằng cách sử dụng ký hiệu và về cơ bản liên quan đến quyền sở hữu.

Thông thường, quy trình cha của trình nền là quy trình init (quy trình đầu tiên được bắt đầu trên hệ thống Unix), trình nền là con của quy trình đó có nghĩa là nó không thuộc quyền kiểm soát trực tiếp của bạn với tư cách là người dùng không có đặc quyền . Mặt khác, việc đưa một chương trình / quá trình xuống nền có nghĩa là bất cứ lúc nào bạn cũng có thể gọi nó trở lại nền trước và / hoặc giết nó.


1
Ngoài ra để trả lời khía cạnh kỹ thuật trên của việc tách rời một quy trình so với việc giữ nó như một đứa con của thiết bị đầu cuối, bạn có thể thử chạy "nohup firefox &"
Odaym

7

Với command &quy trình của bạn sẽ bị giết bởi tín hiệu SIGHUP khi cha mẹ chết.

Sysadmin có quyền truy cập vào một số cách giải quyết, mặc dù.

Trên hệ thống bash, bạn có thể sử dụng:

(trap '' HUP; command) &

Điều này sẽ mở ra một subshell, bẫy HUPtín hiệu với một trình xử lý trống và ampeand / forks nó.

Đầu ra vẫn có thể được chuyển hướng đến sai tty. Hoặc bị lạc.
Bạn có thể khắc phục điều đó với &>command.out, 1>output.outhoặc2>errors.out

Bạn cũng có thể có quyền truy cập, trên hầu hết các hệ thống, vào nohuplệnh.
nohupđơn giản hóa quá trình này rất nhiều. Nó khá chuẩn, nhưng tôi thấy nhiều bản phân phối ARM nhúng bận rộn thiếu nó. Bạn chỉ cần viết:

nohup command &

..và bạn đã hoàn thành. Đầu ra được chuyển hướng, IIRC, đến nohup.out, nhưng tên tệp này có thể được thay đổi bằng một tùy chọn.


2
Chỉ cần lưu ý rằng với ZSH, bạn có thể tách rời phần command &sau với shell disownmà sau đó hoạt động như một phần sau.
toán
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.