Điều gì xác định chính xác nếu một công việc nền được giết khi thoát khỏi vỏ hoặc bị giết?


12

Câu hỏi này đã đưa ra khá một nhiều ( thực sự rất nhiều ), nhưng tôi đang tìm kiếm câu trả lời cho được thường không đầy đủ. Câu hỏi chung là "Tại sao / không công việc của tôi bị giết khi tôi thoát / giết ssh?", Và đây là những gì tôi đã tìm thấy. Câu hỏi đầu tiên là: Thông tin chung như thế nào? Điều sau đây có vẻ đúng với Debian linux hiện đại, nhưng tôi thiếu một số bit; và những gì người khác cần biết?

  1. Tất cả các tiến trình con, backgrounded hay không của một vỏ mở qua một kết nối ssh bị giết với SIGHUP khi kết nối ssh bị đóng chỉ khi các huponexittùy chọn được thiết lập: chạy shopt huponexitđể xem nếu điều này là đúng.

  2. Nếu huponexitlà đúng, thì bạn có thể sử dụng nohuphoặc disownphân tách quá trình từ trình bao để nó không bị giết khi bạn thoát. Hoặc, chạy mọi thứ với screen.

  3. Nếu huponexitlà sai, là mặc định trên ít nhất một số linux hiện nay, thì các công việc nền sẽ không bị giết khi đăng xuất bình thường.

  4. Nhưng ngay cả khi huponexitlà sai, thì nếu kết nối ssh bị hủy hoặc bị rớt (khác với đăng xuất bình thường), thì các quy trình nền sẽ vẫn bị giết. Điều này có thể tránh được bằng disownhoặc nohupnhư trong (2).

  5. Có một số khác biệt giữa (a) các quy trình có quy trình cha là thiết bị đầu cuối và (b) có các quy trình stdin, stdout hoặc stderr được kết nối với thiết bị đầu cuối . Tôi không biết điều gì xảy ra với các quá trình (a) chứ không phải (b) hoặc ngược lại.

Câu hỏi cuối cùng: Làm thế nào tôi có thể tránh hành vi (3)? Nói cách khác, theo mặc định, các quy trình nền của Debian chạy dọc theo sau khi đăng xuất nhưng không phải sau khi kết nối ssh bị hủy. Tôi muốn điều tương tự xảy ra với các quy trình bất kể kết nối được đóng bình thường hay bị tắt. Hoặc, đây là một ý tưởng tồi?

Chỉnh sửa: Một cách khác, quan trọng để giữ công việc bị giết, đó là hoạt động (?) Trong cả hai trường hợp là chạy chúng qua màn hình . Nhưng, câu hỏi liên quan nhiều hơn đến sự hiểu biết khi mọi thứ bị giết và khi họ không: đôi khi mọi người muốn các công việc bị giết khi đăng xuất, chẳng hạn.

Thêm chủ đề: - Làm rõ về tín hiệu (thở dài), công việc và thiết bị đầu cuối kiểm soát - /server/117152/do-background- Processes-get-a-weight-when-global-off - Tiếp tục SSH tác vụ / công việc nền khi đóng SSH - Công việc được đặt trong nền có tiếp tục chạy sau khi đóng phiên SSH không? - Ngăn chặn quá trình nền đang chạy bị dừng sau khi đóng máy khách SSH - Làm cách nào tôi có thể bắt đầu một quy trình qua SSH để nó tiếp tục chạy sau khi tôi ngắt kết nối? - Không thể duy trì công việc từ xa chạy trên OS X - Đóng kết nối SSH

Câu trả lời:


1

Một quá trình không "bị giết bằng SIGHUP" - ít nhất, không phải theo nghĩa chặt chẽ của từ này. Thay vào đó, khi kết nối bị ngắt, quá trình kiểm soát của thiết bị đầu cuối (trong trường hợp này là Bash) được gửi tín hiệu gác máy *, thường được viết tắt là "tín hiệu HUP", hoặc chỉ SIGHUP.

Bây giờ, khi một quá trình nhận được tín hiệu, nó có thể xử lý nó theo bất kỳ cách nào nó muốn **. Mặc định cho hầu hết các tín hiệu (bao gồm HUP) là thoát ngay lập tức. Tuy nhiên, chương trình được tự do bỏ qua tín hiệu thay vào đó, hoặc thậm chí để chạy một số loại chức năng xử lý tín hiệu.

Bash chọn tùy chọn cuối cùng. Trình xử lý tín hiệu HUP của nó kiểm tra xem liệu tùy chọn "huponexit" có đúng không, và nếu vậy, sẽ gửi SIGHUP đến từng quy trình con của nó. Chỉ khi nó kết thúc với điều đó, Bash mới thoát ra.

Tương tự, mỗi tiến trình con có thể tự do làm bất cứ điều gì nó muốn khi nhận được tín hiệu: để nó được đặt thành mặc định (tức là chết ngay lập tức), bỏ qua nó hoặc chạy trình xử lý tín hiệu.

Nohup chỉ thay đổi hành động mặc định cho tiến trình con thành "bỏ qua". Tuy nhiên, khi tiến trình con đang chạy, nó sẽ tự do thay đổi phản hồi của chính nó đối với tín hiệu.

Điều này, tôi nghĩ, là lý do tại sao một số chương trình chết mặc dù bạn đã chạy chúng với nohup:

  1. Nohup đặt hành động mặc định thành "bỏ qua".
  2. Chương trình cần thực hiện một số loại dọn dẹp khi thoát, vì vậy nó cài đặt trình xử lý SIGHUP, ghi đè lên cờ "bỏ qua" một cách tình cờ.
  3. Khi SIGHUP đến, trình xử lý sẽ chạy, dọn sạch các tệp dữ liệu của chương trình (hoặc bất cứ điều gì cần làm) và thoát khỏi chương trình.
  4. Người dùng không biết hoặc quan tâm đến trình xử lý hoặc dọn dẹp và chỉ thấy rằng chương trình đã thoát mặc dù không có tiếng ồn.

Đây là nơi "từ chối" xuất hiện. Một quá trình bị Bash từ chối không bao giờ được gửi tín hiệu HUP, bất kể tùy chọn huponexit. Vì vậy, ngay cả khi chương trình thiết lập trình xử lý tín hiệu riêng, tín hiệu không bao giờ thực sự được gửi, vì vậy trình xử lý không bao giờ chạy. Tuy nhiên, lưu ý rằng nếu chương trình cố gắng hiển thị một số văn bản cho người dùng đã đăng xuất, nó sẽ gây ra lỗi I / O, điều này có thể khiến chương trình thoát ra.

* Và, vâng, trước khi bạn hỏi, thuật ngữ "cúp máy" còn sót lại từ những ngày quay số chính của UNIX.

** Hầu hết các tín hiệu, dù sao. SIGKILL, ví dụ, luôn luôn khiến chương trình chấm dứt ngay lập tức, định kỳ.


2

Điểm 1-4 là chính xác. Tôi không biết gì về điểm 5. Đối với điểm cuối cùng của bạn, một ứng dụng tốt, màn hình , sẽ cho phép bạn để tất cả các quy trình chạy đến kết thúc tự nhiên của chúng, bất kể bạn chấm dứt kết nối của mình như thế nào. Màn hình là trong repos.

Mô tả người đàn ông của màn hình không dễ đọc, nhưng, trong số những thứ khác, nó nói:

Khi màn hình được gọi, nó sẽ tạo một cửa sổ duy nhất có vỏ trong đó (hoặc lệnh được chỉ định) và sau đó thoát ra để bạn có thể sử dụng chương trình như bình thường. Sau đó, bất cứ lúc nào, bạn có thể tạo các cửa sổ mới (toàn màn hình) với các chương trình khác trong đó (bao gồm nhiều shell hơn), giết các cửa sổ hiện có, xem danh sách các cửa sổ, bật và tắt đăng nhập đầu ra, sao chép và dán văn bản giữa các cửa sổ, xem lịch sử cuộn lại, chuyển đổi giữa các cửa sổ theo bất kỳ cách nào bạn muốn, v.v ... Tất cả các cửa sổ chạy chương trình của chúng hoàn toàn độc lập với nhau. Các chương trình tiếp tục chạy khi cửa sổ của chúng hiện không hiển thị và ngay cả khi toàn bộ phiên màn hình được tách ra khỏi thiết bị đầu cuối của người dùng. Khi một chương trình kết thúc, màn hình (theo mặc định) sẽ giết chết cửa sổ chứa nó. Nếu cửa sổ này ở phía trước, màn hình sẽ chuyển sang cửa sổ trước; nếu không còn lại, màn hình thoát.

Tôi đã nhấn mạnh phần quan trọng nhất: bạn có thể tách cửa sổ bằng lệnh Ctrl + a + d, và sau đó bạn có thể tắt / đăng xuất phiên của mình và cửa sổ hiện đang tách ra sẽ tiếp tục hoạt động, với các chương trình bên trong vẫn đang chạy. Khi bạn kết nối trở lại, ví dụ bằng cách bắt đầu một phiên ssh mới, lệnh màn hình -r sẽ tiếp tục phiên màn hình đã được tách ra trước đó, với tất cả đầu ra thành lỗi / đầu ra tiêu chuẩn rõ rà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.