2016-08-12 5 views
1

Ich bin verwirrt über die Weiterleitung von Signalen an Kindprozesse mit Traps. Sagen wir, ich habe zwei Skripte:Bash Trap '' vs Trap Funktion Signale übergeben

a.sh

#!/bin/bash 

# print the process id 
echo $$ 

cleanup() { 
    rv=$? 
    echo "cleaning up $rv" 
    exit 
} 

sleep 5 
trap '' SIGTERM # trap cleanup SIGTERM 
echo 'cant stop wont stop' 
./b.sh 
echo 'can stop will stop' 
trap - SIGTERM 
sleep 4 
echo 'done' 

b.sh

#!/bin/bash 
sleep 4; 
echo 'b done' 

Wenn ich a.sh ausführen und dann aus einem anderen Fenster töten die Prozessgruppe mit kill -- -PGID wird die SIGTERM ignoriert und nicht an b.sh weitergegeben. Aber wenn ich trap cleanup SIGTERM mache, durchläuft das SIGTERM b.sh und beendet es. Warum gibt meine Falle in einem Fall das Signal und nicht das andere?

Antwort

1

Das ist interessant. Zitieren man 7 signal:

Ein über fork (2) erstellt Kind erbt eine Kopie der Signal Dispositionen seiner Eltern. Während einer Ausführung (2) werden die Dispositionen der gehandhabten Signale auf den Standardwert zurückgesetzt; die Dispositionen der ignorierten Signale bleiben unverändert.

In Ihrem Fall erhält das Kind immer , weil es sich in derselben Prozessgruppe befindet. Das Problem ist, was es damit macht.

Wenn das übergeordnete ignoriert , durch die Regel oben, so tut das Kind, so dass das Kind überlebt. Wenn das übergeordnete Objekt den Wert abfängt, wird der Handler des untergeordneten Elements zurückgesetzt, und es wird als Standardaktion absterben.

1

Vom trap man page:

trap [Aktion Bedingung ...]

Wenn Aktion null ist (""), so wird die Schale jeweils angegebene Bedingung ignorieren, wenn es entsteht.

Also, wenn Sie TRAP '' SIGTERM ausführen, die SIGTERM Zustand ignoriert. Versuchen Sie stattdessen, einen Leerzeichen-Wert zu verwenden und zu überprüfen, ob es funktioniert:

sleep 5 
trap ' ' SIGTERM # Note the space (' ')!! 

echo 'cant stop wont stop' 
./b.sh 

echo 'can stop will stop' 
trap - SIGTERM 

sleep 4 
echo 'done'