Tập lệnh Bash không thấy SIGHUP?


11

Tôi đã có đoạn script sau:

#!/bin/bash
echo "We are $$"
trap "echo HUP" SIGHUP
cat    # wait indefinitely

Khi tôi gửi SIGHUP(sử dụng kill -HUP pid), không có gì xảy ra.

Nếu tôi thay đổi tập lệnh một chút:

#!/bin/bash
echo "We are $$"
trap "kill -- -$BASHPID" EXIT    # add this
trap "echo HUP" SIGHUP
cat    # wait indefinitely

... Sau đó, tập lệnh thực hiện echo HUPđúng khi nó thoát (khi tôi nhấn Ctrl + C):

roger@roger-pc:~ $ ./hupper.sh 
We are 6233
^CHUP

Chuyện gì đang xảy ra vậy? Tôi nên gửi tín hiệu như thế nào (không nhất thiết phải như vậy SIGHUP) cho tập lệnh này?


4
Tín hiệu sẽ được gửi và bộ xử lý tín hiệu sẽ thực thi khi catquá trình kết thúc. Hãy thử tập lệnh gốc của bạn và nhấn Ctrl+Dđể thực hiện catquá trình thoát. Trong khi catquá trình ở phía trước, HUPtín hiệu không được tác động. Hãy thử lại với catthay thế bằng read(một vỏ tích hợp).
Kusalananda

Hoàn hảo. Có ai đó thích biến điều đó thành một câu trả lời?
Roger Lipscombe

Tôi biết nó hoạt động theo cách đó, nhưng tôi sẽ để ai đó có cái nhìn sâu sắc hơn tôi vào câu trả lời và nơi mà câu trả lời.
Kusalananda

while true; do read; doneCuối cùng tôi đã sử dụng , nếu không, việc nhập văn bản cũng khiến nó thoát ra và tôi muốn nó thoát khỏi Ctrl + C.
Roger Lipscombe

Câu trả lời:


21

Hướng dẫn Bash nêu:

Nếu bash đang chờ lệnh hoàn thành và nhận được tín hiệu đặt bẫy, bẫy sẽ không được thực thi cho đến khi lệnh hoàn thành.

Điều đó có nghĩa là mặc dù tín hiệu được nhận bashkhi bạn gửi nó, bẫy của bạn trên SIGHUP sẽ chỉ được gọi khi catkết thúc.

Nếu hành vi này là không mong muốn, thì hãy sử dụng các bashnội trang (ví dụ read+ printftrong một vòng lặp thay vì cat) hoặc sử dụng các công việc nền (xem câu trả lời của Stéphane ).


9

@xhienne đã giải thích lý do tại sao , nhưng nếu bạn muốn tín hiệu được xử lý ngay lập tức (và không thoát khỏi tập lệnh), bạn có thể thay đổi mã của mình thành:

#! /bin/bash -
interrupted=true
trap 'interrupted=true; echo HUP' HUP

{ cat <&3 3<&- & pid=$!; } 3<&0

while
  wait "$pid"
  ret=$?
  "$interrupted"
do
  interrupted=false
done
exit "$ret"

Điệu nhảy nhỏ với các mô tả tập tin là để giải quyết vấn đề bashchuyển hướng stdin sang /dev/nullcác lệnh được khởi chạy trong nền.


Điều này có hoạt động không vì khối mã chạy trong một lớp con?
Pysis
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.