Tại sao, su su su -c <lệnh> & dường như cho phép một lệnh chạy trong nền mà không bị treo


11

Tôi đã giúp một đồng nghiệp đang gặp vấn đề với quá trình làm nền liên tục chết.

Tôi phát hiện ra rằng họ đang bắt đầu quá trình nền bằng cách đăng nhập vào máy chủ và thực thi:

su - <user> -c '<command>' &

"Aha", tôi kêu lên. "Nếu bạn bắt đầu một lệnh với" & "nó sẽ bị treo khi bạn thoát khỏi thiết bị đầu cuối điều khiển. Bạn cần sử dụng một cái gì đó như nohup để đạt được điều này. Thực sự quá trình này cần hỗ trợ chạy như một daemon, tut tut."

Chúng tôi đã thử nghiệm lệnh trên để chứng minh quan điểm của tôi và ... nó dường như hoạt động: quá trình bắt đầu bằng lệnh không thoát khi chúng tôi thoát khỏi thiết bị đầu cuối chạy lệnh trên.

lệnh là một tập lệnh Python tùy chỉnh có đầu ra đi đến một tệp. Theo như tôi có thể nói, không có khả năng "daemonize" thông minh nào trong kịch bản. Nó không thực hiện bất kỳ điều gì cần thiết để chạy như một daemon được liệt kê trong Wikipedia: Daemon (tính toán): Trang tạo .

Chạy lệnh như vậy hành xử như mong đợi:

<command> &
exit

Trong trường hợp trên, quá trình nền bắt đầu bằng lệnh thoát khi chúng ta thoát khỏi thiết bị đầu cuối.

Câu hỏi của tôi là:

  1. Điều gì đang xảy ra khi chúng ta thêm "su - -c &" ngăn quá trình thoát khi thiết bị đầu cuối của chúng ta thoát. Tôi muốn hiểu chi tiết về thiết bị đầu cuối điều khiển, đầu vào và đầu ra tiêu chuẩn, v.v.

  2. Đây có phải là một cách hợp lý để đạt được mục tiêu chạy lệnh này như là một quá trình nền. Nếu không, tai sao không?

Tôi muốn tuyên truyền các thực tiễn tốt nhất trong công ty của mình, nhưng tôi cần có khả năng chứng minh và sao lưu mọi khuyến nghị tôi đưa ra.

Tôi cũng muốn hiểu chính xác những gì đang diễn ra.

Câu trả lời:


12

Có một số cách mà một quá trình có thể bị giết vì một thiết bị đầu cuối sắp chết.

  1. Cách đầu tiên là trình điều khiển đầu cuối trong kernel gửi tín hiệu SIGHUP đến quá trình điều khiển mà đầu cuối là đầu cuối điều khiển . Trong hầu hết các trường hợp, quá trình kiểm soát là lớp vỏ ban đầu được bắt đầu trong thiết bị đầu cuối và thiết bị đầu cuối kiểm soát của nó là lớp mà stdin, stdout và stderr của nó được kết nối. Một quá trình sẽ bị ngắt kết nối khỏi thiết bị đầu cuối kiểm soát nếu nó gọi setsid.

  2. Cách thứ hai là shell, khi nhận được SIGHUP, sẽ gửi lại tín hiệu đó đến các quy trình con của nó - chính xác hơn là các công việc nền của nó. Một số shell (ksh, bash, zsh) có disownsẵn nội dung để báo cho shell không gửi SIGHUP cho một công việc cụ thể.

  3. Nếu thiết bị đầu cuối biến mất và một chương trình cố gắng đọc từ nó, nó sẽ được thông báo về tình trạng cuối tập tin (hoặc có thể là EIO cho một công việc nền). Nếu thiết bị đầu cuối biến mất và một chương trình cố gắng ghi vào nó, ghi sẽ trả về với lỗi EIO. Những thứ này có thể khiến chương trình thoát ra.

Vì vậy, điều suthay đổi ở đây là (2) thường sẽ khiến lớp vỏ ban đầu giết chết công việc nền, nhưng vì quá trình nền đó đang chạy như một người dùng khác, tín hiệu không thể được gửi và quá trình nền vẫn tiếp tục.


Tôi đã thấy người dùng root làm chroot --userspec root:root / sh -c "exec some_forever_process" &. Công việc đang chạy như một người dùng, không có rõ ràng nohuptrước hoặc disownsau. Vì vậy, trong trường hợp này, làm thế nào tín hiệu không thể được gửi khi thoát hạn?
Toddius Zho

@ToddiusZho Presumable some_forever_processđược dự định chạy mãi mãi (một daemon) và do đó tự bảo vệ mình khỏi việc nhận SIGHUP từ lối ra cuối (bằng cách chạy trong nhóm quy trình riêng của nó).
Gilles 'SO- ngừng trở nên xấu xa'

bash / tail không bảo vệ chống lại SIGHUP, nhưng nó vẫn hoạt động: `` `local $ ssh root @ REMOTE_HOST remote # chroot --userspec root: root / sh -c" exec bash -c 'tail -f / dev / null '"& [1] 6376 từ xa # ps -p $! --no-title -o pid, uid, lệnh -ww 6376 0 tail -f / dev / null remote # exit local $ ssh root @ REMOTE_HOST remote # ps -p 6376 --no-title -o pid, uid, lệnh -ww 6376 0 đuôi -f / dev / null `` `
Toddius Zho
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.