kill
Lệnh của bạn là ngược.
Giống như nhiều lệnh UNIX, các tùy chọn bắt đầu bằng dấu trừ phải đến trước, trước các đối số khác.
Nếu bạn viết
kill -INT 0
nó xem -INT
tùy chọn này và gửi SIGINT
đến 0
( 0
là một số đặc biệt có nghĩa là tất cả các quy trình trong nhóm quy trình hiện tại).
Nhưng nếu bạn viết
kill 0 -INT
Nó thấy 0
, quyết định không có thêm tùy chọn, vì vậy sử dụng SIGTERM
theo mặc định. Và gửi nó cho nhóm quy trình hiện tại, giống như khi bạn đã làm
kill -TERM 0 -INT
(nó cũng sẽ cố gửi SIGTERM
đến -INT
, điều này sẽ gây ra lỗi cú pháp, nhưng nó sẽ gửi SIGTERM
đến 0
đầu tiên và không bao giờ đi xa đến thế.)
Vì vậy, kịch bản chính của bạn đang nhận được SIGTERM
trước khi nó chạy wait
và echo DONE
.
Thêm vào
trap 'echo got SIGTERM' TERM
ở trên cùng, ngay sau
trap 'killall' INT
và chạy nó một lần nữa để chứng minh điều này.
Như Stephane Chazelas chỉ ra, những đứa trẻ của bạn ( process1
, v.v.) sẽ SIGINT
mặc định bỏ qua .
Trong mọi trường hợp, tôi nghĩ gửi SIGTERM
sẽ có ý nghĩa hơn.
Cuối cùng, tôi không chắc liệu có kill -process group
được đảm bảo đi đến trẻ em trước không. Bỏ qua các tín hiệu trong khi tắt có thể là một ý tưởng tốt.
Vì vậy, hãy thử điều này:
#!/bin/bash
trap 'killall' INT
killall() {
trap '' INT TERM # ignore INT and TERM while shutting down
echo "**** Shutting down... ****" # added double quotes
kill -TERM 0 # fixed order, send TERM not INT
wait
echo DONE
}
./process1 &
./process2 &
./process3 &
cat # wait forever