Điều gì xảy ra với các công việc nền sau khi thoát khỏi vỏ?


9

Từ sự hiểu biết của tôi, công việc là đường ống bắt đầu từ một vỏ nhất định và bạn có thể quản lý các công việc ( fg, bg, Ctrl-Z) từ bên trong vỏ này. Một công việc có thể bao gồm nhiều quy trình / lệnh.

Câu hỏi của tôi là những gì xảy ra với những công việc này khi bản gốc, chứa vỏ thoát? Giả sử huponexit không được đặt để các tiến trình nền tiếp tục chạy sau khi thoát khỏi trình bao.

Giả sử tôi đã làm:

$ run.sh | grep 'abc' &
[1] job_id

Sau đó tôi thoát khỏi cái vỏ này. Tôi sẽ nhập một vỏ mới và chạy jobsvà không thấy gì rõ ràng. Nhưng tôi có thể làm ps aux | grep run.shvà thấy quá trình này đang chạy và tôi cũng sẽ làm ps aux | grep grepvà thấy quá trình grep 'abc'chạy.

Có cách nào để lấy ID công việc cho toàn bộ đường ống để tôi có thể giết nó trong một lần hay tôi phải giết tất cả các quy trình riêng biệt với một trình bao khác sau khi tôi thoát khỏi trình bao ban đầu? (Tôi đã thử cái sau và nó hoạt động, nhưng có vẻ như rắc rối để theo dõi tất cả các quy trình.)

Câu trả lời:


7

Khi shell thoát ra, nó có thể gửi tín hiệu HUP đến các công việc nền và điều này có thể khiến chúng thoát ra. Tín hiệu SIGHUP chỉ được gửi nếu chính vỏ nhận được SIGHUP, tức là chỉ khi thiết bị đầu cuối biến mất (ví dụ vì quá trình giả lập thiết bị đầu cuối bị chết) chứ không phải nếu bạn thoát khỏi vỏ bình thường (với exitnội dung dựng sẵn hoặc bằng cách gõ Ctrl+ D). Xem trong trường hợp nào SIGHUP không được gửi đến một công việc khi bạn đăng xuất? Có biến thể UNIX nào mà quá trình con chết với cha mẹ của nó không? để biết thêm chi tiết. Trong bash, bạn có thể đặt huponexittùy chọn cũng gửi SIGHUP tới các công việc nền trên lối thoát bình thường. Trong ksh, bash và zsh, gọidisowntrên một công việc sẽ loại bỏ nó khỏi danh sách các công việc để gửi SIGHUP tới. Một quá trình nhận SIGHUP có thể bỏ qua hoặc bắt tín hiệu, và sau đó nó sẽ không chết. Sử dụng nohupkhi bạn chạy một chương trình làm cho nó miễn nhiễm với SIGHUP.

Nếu quá trình không bị giết do SIGHUP có thể xảy ra thì nó vẫn bị bỏ lại phía sau. Không còn gì để liên hệ nó với số công việc trong vỏ.

Quá trình có thể vẫn chết nếu nó cố truy cập vào thiết bị đầu cuối nhưng thiết bị đầu cuối không còn tồn tại. Điều đó phụ thuộc vào cách chương trình phản ứng với một thiết bị đầu cuối không tồn tại.

Nếu công việc chứa nhiều quy trình (ví dụ: một đường ống), thì tất cả các quy trình này nằm trong một nhóm quy trình . Các nhóm quy trình được phát minh chính xác để nắm bắt khái niệm về một công việc shell được tạo thành từ nhiều quy trình liên quan. Bạn có thể thấy các quy trình được nhóm theo nhóm quy trình bằng cách hiển thị ID nhóm quy trình của họ (PGID - thông thường là ID quy trình của quy trình đầu tiên trong nhóm), ví dụ như với ps lLinux hoặc một cái gì đó có thể di chuyển được ps -o pid,pgid,tty,etime,comm.

Bạn có thể giết tất cả các quy trình trong một nhóm bằng cách chuyển một đối số phủ định tới kill. Ví dụ: nếu bạn đã xác định rằng PGID cho đường ống bạn muốn giết là 1234, thì bạn có thể giết nó bằng

kill -TERM -1234

2

Nói chung họ vẫn chạy, nhưng bạn nên sử dụng nohup, nếu bạn quên hoặc thay đổi ý định sử dụng từ chối.

mike@mike-laptop4:~$ sleep 500
^Z
[1]+  Stopped                 sleep 500
mike@mike-laptop4:~$ bg
[1]+ sleep 500 &
mike@mike-laptop4:~$ jobs
[1]+  Running                 sleep 500 &
mike@mike-laptop4:~$ disown %1
mike@mike-laptop4:~$ jobs
mike@mike-laptop4:~$ 

và để tiêu diệt, bạn có thể kiểm tra bash cha mẹ bằng ps -efestest, nếu bash có các chức năng nền, bạn cũng có thể cần phải giết chúng
mikejonesey
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.