2012-02-22 31 views
5

Tôi có một bash script "kịch bản" mà khoảng trông giống như:bash ống & SIGTERM

#!/bin/bash 

cmd1 | cmd2 | cmd3 

Khi tôi làm một kill script (hay chính xác hơn khi tôi làm một 'stop script' trong supervisord), không phải tất cả cmd * bị giết. Làm thế nào tôi có thể chắc chắn rằng họ đang chấm dứt cùng với kịch bản mà sinh ra chúng?

+0

Có thể nên ở [su]? –

Trả lời

5

Giám sát có một tùy chọn killasgroup (sai theo mặc định) xác định có nên truyền tín hiệu dừng/chấm dứt cho các tiến trình con hay không.

[program:script] 
command=script 
killasgroup=true 

https://github.com/Supervisor/supervisor/blob/master/supervisor/process.py#L354

+0

Có vẻ rất hứa hẹn mặc dù tôi không thể kiểm tra điều này vào lúc này: Tôi đã thêm một kiểm tra dựa trên 'cha mẹ 'vào tất cả các tập lệnh của tôi để các tiến trình con tự thoát khi quá trình cha mẹ thay đổi (thành' 1 '). – jldupont

+2

* (Bạn có thể cũng muốn đặt true là stopasgroup tùy chọn để chắc chắn rằng hành vi này được sử dụng trong mọi tình huống (ví dụ với lệnh "restart"). Lưu ý rằng các tùy chọn đó không có trong các phiên bản cũ của người giám sát. – Andomar

2

Không chắc chắn về cách sử dụng supervisord, nhưng với pkill bạn có thể sử dụng tùy chọn -P để giết từ quy trình gốc cho tất cả trẻ em. Đây là cây quá trình (bắt đầu từ daemon ssh chạy của tôi).

$ pstree -a -p 1792 
sshd,1792 
    ├─sshd,27150 
    │ └─sshd,27153 
    │  └─zsh,27154 
    │   └─test.sh,27325 ./test.sh 
    │    └─cat,27326 
    └─sshd,27182 
     └─sshd,27184 
      └─zsh,27185 
       └─pstree,27357 -a -p 1792 

Trong một phiên tôi có một kịch bản test.sh với pid 27.325, và ở bên kia Tôi đang chạy lệnh pstree -a -p 1792 (vì sshd có pid 1792)

Và sau khi tôi chạy pkill -TERM -P 27325:

$ pstree -a -p 1792 
sshd,1792 
    ├─sshd,27150 
    │ └─sshd,27153 
    │  └─zsh,27154 
    └─sshd,27182 
     └─sshd,27184 
      └─zsh,27185 
       └─pstree,27387 -a -p 1792 

Câu trả lời này chủ yếu được lặp lại từ câu trả lời khác này trên luồng ngăn xếp: https://stackoverflow.com/a/392155/263969

+0

+1 Thú vị nhưng không chính xác những gì tôi cần. – jldupont

0

Một giải pháp khác là để bẫy SIGTERM và giết tất cả trẻ em trong cái bẫy-mã.

Điều duy nhất là vỏ chạy mã bẫy cho tín hiệu nhận được chỉ sau khi lệnh hiện đang chạy hoàn thành - vì vậy trong trường hợp của bạn, điều này một mình sẽ không hữu ích.

Tuy nhiên, bẫy sẽ được chạy theo cách "không đồng bộ" nếu trình bao đang ở trạng thái "chờ".

#!/usr/bin/env bash 
trap 'kill 0' TERM 
(cmd1 | cmd2 | cmd3) & wait 

kill 0 gửi SIGTERM đến tất cả các quy trình trong nhóm quy trình hiện tại.

LƯU Ý: Tôi đang nói về Bash ở đây.

Các vấn đề liên quan