2010-03-26 42 views
20

Tôi có một tập hợp các tập lệnh được kiểm soát bởi một tập lệnh chính. Tôi muốn bẫy tín hiệu ctrl + c trong tập lệnh chính và truyền cho người khác. Các kịch bản khác cũng nên bẫy tín hiệu này (từ tập lệnh chính) và làm sạch một số ...Làm thế nào để truyền tín hiệu thông qua một tập hợp các tập lệnh?

Tôi đã cố gắng gửi kill -s SIGINT cho trẻ em, nhưng có vẻ như chúng không thể nhận tín hiệu (thậm chí nếu trap 'Cleanup' SIGINT được xác định trên tập lệnh trẻ em)

Bất kỳ manh mối nào để nhận ra điều này?

+1

Sẽ hữu ích nếu bạn hiển thị các ví dụ cụ thể về cha mẹ và trẻ em viết tắt. –

+0

Xem câu trả lời của tôi tại câu hỏi khác của bạn để có giải pháp khả thi. http://stackoverflow.com/questions/2524937/how-to-send-a-signal-sigint-from-script-to-script-bash –

Trả lời

-1

Tôi không chắc chắn ý của bạn là gì bởi "các tập lệnh khác nên bẫy tín hiệu này từ tập lệnh chính"? Làm thế nào một kịch bản phụ có thể sử dụng mã trong kịch bản chính để bẫy một tín hiệu?

Tôi không muốn thử và viết nhiều mã cho bạn vì tôi không biết chính xác ý bạn là gì bởi "tập lệnh được điều khiển bởi chính", nhưng có lẽ bạn khởi chạy một số quy trình con, sau đó có vòng điều khiển kiểm tra xem các tập lệnh khác đã thoát chưa và có thể lấy trạng thái thoát của chúng không? Nếu đó là trường hợp, điều có ý nghĩa nhất đối với tôi là cho mỗi kịch bản để làm bẫy và dọn dẹp riêng của nó. Khi kịch bản chính bẫy một tín hiệu, nó có thể nếu bạn muốn truyền tín hiệu cho tất cả trẻ em (thông qua kill -s <signal> pid). Khi một quá trình con bẫy một tín hiệu, nó có thể trở về một trạng thái thoát cho biết rằng nó đã bị chấm dứt bởi tín hiệu đó. Sau đó, chính có thể xử lý trạng thái thoát đó một cách thích hợp - có lẽ giống như cách nó nhận được chính tín hiệu đó. (Các chức năng của Shell là bạn của bạn.)

+0

Thực ra tôi gửi 'kill -s pid' cho trẻ nhưng chúng có thể không bắt được nó (ngay cả với 'bẫy' Dọn dẹp '2' đang được xác định). để trẻ em bị giết mà không cần dọn dẹp. Các kịch bản chính không biết nhiều về những gì các em đang làm, vì vậy anh ta không thể tự dọn dẹp bản thân – Debugger

+0

@debugger: Ý em là gì các em không thể bắt được tín hiệu? Cái bẫy đó trong kịch bản chính à? Nó cần phải được ở trẻ em. – Cascabel

+0

Jefromi: bẫy được chỉ định trên cả tập lệnh chính và trẻ em, mặc dù chúng gọi các hàm khác nhau. Vì vậy, kịch bản chính nắm bắt các 'ctrl-c' signal và gửi tín hiệu cho các trẻ khác nhau. Sau đó, có bẫy được xác định trên trẻ em rằng "nên" bắt tín hiệu từ kịch bản chính và gọi một chức năng cụ thể – Debugger

18

Ví dụ sau minh họa một tập lệnh mẹ thực hiện điều gì đó (sleep 5) sau khi bắt đầu hai đứa trẻ làm việc riêng của chúng (cũng là sleep 5). Khi cha mẹ thoát (vì bất kỳ lý do gì) nó báo hiệu trẻ em chấm dứt (không SIGINT, chấm dứt được báo hiệu bởi SIGTERM, cũng là tín hiệu kill mặc định). Những đứa trẻ sau đó làm điều của họ trên tiếp nhận của SIGTERM. Nếu trẻ em là những chữ viết riêng của chúng, tôi khuyên bạn nên thay đổi cái bẫy trên TERM thành một cái bẫy trên EXIT để trẻ dọn dẹp bất kể nguyên nhân chấm dứt của chúng là gì (miễn là nó có thể bị trói).

Lưu ý việc sử dụng wait của tôi. Bash không làm gián đoạn các lệnh không được xây dựng khi nó nhận được một tín hiệu. Thay vào đó, nó chờ cho họ hoàn thành và xử lý tín hiệu sau khi lệnh được thực hiện. Nếu bạn sử dụng wait, bash sẽ dừng ngay lập tức và xử lý tín hiệu ngay lập tức.

#!/usr/bin/env bash 

trap 'echo parent shutting down; kill $(jobs -p)' EXIT 

{ trap 'echo child 1 signaled' TERM; sleep 5 & wait; } & 
{ trap 'echo child 2 signaled' TERM; sleep 5 & wait; } & 

sleep 5 
+0

làm thế nào để ngủ 5 bị giết trong trẻ em khi một tín hiệu TERM được gửi đến kịch bản này? – Gabriel

+0

Chẳng lẽ giấc ngủ ở trẻ em dài hơn 5 ví dụ? Như thế này, họ kết thúc trước khi giấc ngủ trong bố mẹ được thực hiện và 'giết' không thể tìm được công việc nữa. –

0

CHỦ PHỤ HUYNH SCRIPT HEADER TRƯỚC CHỦ LOOP :::

#Catch control-c and clean up testd instances if necessary 
cleanup() { 
    clear 
    echo "Caught Signal. Shutting Down MAIN." 
    if [ "$MAIN_on" -eq 1 ] 
    then 
    M_shutdown 
    fi 
    exit 1 
    } 

Trong phần chính của kịch bản, khi bạn đẻ trứng subprocesses bạn duy trì một mảng với id proc của mỗi. Để tải PID vào mảng, hãy đặt giá trị cho quá trình sinh sản cuối cùng, ví dụ: đặt sau đây sau mỗi vỏ đẻ trứng.

proc_id_array[1]=$! 

Nội dung của M_shutdow sẽ giống như ...

M_shutdown() { 

    if [ "$MAIN_on" -eq 1 ] 
    then 
    echo "Stopping Main" 
    echo "shutting down active subscripts" 
    count_proc_id=1 


while [ "$count_proc_id" -lt "$max_proc_id" ] 
     do 

      kill ${proc_id_array[$count_proc_id]} > /dev/null 2>&1 
      DATE=$(date +%m%d%y-%k:%M) 
      echo "$DATE: ${proc_name_array[$count_proc_id]} \(PID: ${proc_id_array[$count_proc_id]}\) stopped." >> $logfile    
      proc_id_array[$count_proc_id]="A" 
      count_proc_id=`expr $count_proc_id + 1` 
     done 


     echo "MAIN stopped" 
     MAIN_on=0 

     sleep 5 
     else 
     echo "MAIN already stopped." 
     sleep 1 
     fi 
    } 
4

Bạn đã cố gắng: 1) Thiết lập bẫy của bạn trong mỗi kịch bản (master/Childs), nơi bạn cần đến chúng 2) Gửi để làm chủ một kill với nó PID phủ nhận, để giết các nhóm quá trình toàn , Ý tôi là:

kill -15 -$PID 

giết người | grep -C1 Phủ định

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