2012-02-13 32 views
27

Khi nhận được tín hiệu, tôi có thể thực hiện một số lệnh bằng cách sử dụng trap. Ví dụ:Xác định tên tín hiệu nhận được trong Bash

trap 'echo hello world' 1 2 

Nếu bất kỳ tín hiệu nào được chỉ định nhận được, thế giới hello 'được hiển thị.

Nhưng làm cách nào tôi có thể in/xác định tên tín hiệu nhận được?

Trả lời

35

(Nếu bạn chỉ có số của một tín hiệu và muốn tên, kill -l $SIGNAL_NUM in tên của một tín hiệu, bạn có thể tránh điều đó bằng cách sử dụng các tên tín hiệu thay vì con số trong cuộc gọi của bạn để trap như dưới đây.)

This answer nói rằng cách duy nhất để xác định tín hiệu nào bạn bị mắc kẹt trong bash là viết một trình bao bọc riêng cho từng tín hiệu khác nhau mà bạn muốn bẫy. Another answer on that same question cung cấp một chức năng bao bọc để làm điều đó cho bạn:

Code:

#!/bin/bash 

trap_with_arg() { 
    func="$1" ; shift 
    for sig ; do 
     trap "$func $sig" "$sig" 
    done 
} 

func_trap() { 
    echo Trapped: $1 
} 

trap_with_arg func_trap INT TERM EXIT 

read # Wait so the script doesn't exit. 

Nếu tôi chạy đó, sau đó tôi có thể gửi tín hiệu đến quá trình này và tôi nhận được kết quả như

Trapped: INT 
Trapped: TERM 
Trapped: EXIT 
+0

Cảm ơn. Nhưng nó sẽ không làm việc cho tôi. Hàm trap_with_arg() sẽ chặn cho đến khi nhận được tín hiệu. Tôi muốn tên tín hiệu được hiển thị khi nhận được tín hiệu - trong khi kịch bản đang được thực hiện. Trong trường hợp của tôi, tôi không chờ đợi tín hiệu. Bất cứ khi nào nó đến, cần phải được in. –

+8

'trap_with_arg()' không chặn. Nó lặp qua đầu vào của nó, thiết lập các trình xử lý bẫy và sau đó trả về. – perelman

+0

Lunar Mushrooms, có vẻ như nó bị chặn vì bẫy không được xử lý trong khi các lệnh trong tập lệnh của bạn đang chạy. Nếu bạn báo hiệu kịch bản của bạn trong khi nó đang ở giữa một 'giấc ngủ', nó sẽ không thực hiện bẫy của bạn cho đến khi' ngủ' đã hoàn thành. Nó không phải là không đồng bộ. Bẫy sẽ bắt tín hiệu giữa các lệnh trong tập lệnh của bạn. – Ray

6

Trong vòng cái bẫy (khi được kích hoạt thông qua tín hiệu), $? biến ban đầu được đặt thành số tín hiệu cộng với 128, vì vậy bạn có thể gán số tín hiệu cho một biến bằng cách làm cho tuyên bố đầu tiên của hành động bẫy để một cái gì đó giống như

sig=$(($? - 128)) 

Sau đó bạn có thể lấy tên của tín hiệu sử dụng lệnh giết

kill -l $sig 
+1

Điều đó sẽ tốt đẹp, nhưng nó không hoạt động với tôi trên Linux 3.10 với Bash 4.3.30: '$?' Là 0 ở đầu bộ xử lý tín hiệu mặc dù nó đã được gọi bởi tín hiệu 'TERM'. –

+0

Điều này có vẻ như là câu trả lời hay nhất vì nó đơn giản hơn. – codeforester

1

một cách đơn giản để làm điều này:

_handler() { 
    signal=$1 
    echo signal was $signal 
} 

trap '_handler SIGTERM' SIGTERM 
trap '_handler SIGINT' SIGINT 
Các vấn đề liên quan