2010-03-26 8 views
11

ich zu stoppen wollen ein Signal von Script-A.sh senden so in Script-A.sh Script-B.sh i verwenden Sie den BefehlWie sende ich ein Signal SIGINT von Skript zu Skript? BASH

(senden SIGINT Script-B.sh)
kill -2 $ PID_Script-B.sh

und in Script-B.sh fangen i das Signal und Anruffunktion reinigen

Falle 'Clean' 2

Es funktioniert nicht, stattdessen wird das Script-.B.sh sofort getötet, ohne die Clean !!

Was ich bemerken ist auch, dass, wenn ich von Terminal zu jedem Skript SIGINT möchten senden, die sie einfängt, wird ein ctrl-c richtig eingefangen werden, aber nicht, wenn ich das Signal über den Befehl kill -2 $pid_of_script

Jede Idee geben über der Unterschied zwischen den beiden Methoden zum Senden des SIGINT (ctrl-c VS kill -2 $pid_of_script), und wie kann ich ein SIGINT von einem Skript zum anderen senden?

Grüße,

Debugger

Antwort

12

Ich war in der Lage, das Verhalten Sie berichten zu reproduzieren. Meine Hypothese ist, dass das Skript läuft von eine nicht interaktive Shell (als Kind eines Skripts) SIGINT, die ein Tastatursignal ist, wird ignoriert.

Von info bash:

Hintergrundprozesse sind solche, deren ID-Prozessgruppe unterscheidet sich von der Terminals; Solche Prozesse sind immun gegen tastaturgenerierte Signale.

Ich habe festgestellt, dass, wenn Sie trap und kill ein anderes Signal wie SIGUSR1 verwendet es funktioniert.

Zusätzliche Informationen aus man bash:

Non-builtin durch bash ausführen Befehle haben Handler Signal auf die Werte gesetzt, indem die Schale von ihrem Elternteil vererbt. Wenn die Jobsteuerung nicht wirksam ist, ignorieren asynchrone Befehle SIGINT und SIGQUIT zusätzlich zu diesen geerbten Handlern.

und

Wenn bash auf einen Befehl wartet abzuschließen und empfängt ein Signal, für das eine Falle gestellt wurde, wird die Falle nicht bis der Befehl ausgeführt ausgeführt werden.

und

Jede Falle auf SIGCHLD wird für jedes Kind ausgeführt, beendet.

+0

Das erste Bit von bash (1) scheint eine Erklärung. Außerdem scheint * zsh * OK zu funktionieren. –

+0

Entschuldigung für diese späte Antwort. Du hast recht, nicht alle Signale können für Kinder eingefangen werden, aber manche. SIGUSR1 hat für mich genauso funktioniert wie SIGTERM, aber nicht in allen Bash-Versionen, weil ich einen Segmentierungsfehler von einem Skript in bash 3.00.16 bekommen habe, als ich versucht habe, das Signal vom Vater an den Sohn zu senden !!! Andere Zeiten, die die gleiche Version verwenden, werden das Signal ignorieren, ohne es abzufangen (in der Kinderebene). Aber neuere Versionen funktionieren gut und verbreiten alle Signale korrekt. Vielen Dank für Ihre Hilfe. – Debugger

+0

ok. Führen Sie scriptA Shell-Skript aus und rufen Sie scriptB (source it) wie ". scriptB.sh param1 param2 .. paramN" auf. So fängt es sauber für Sig 2/INT –

0

In Skript A: Trap-Funktion wird wie folgt aussehen, die die Funktion trap_mesg() in scriptA.sh aufrufen wird. KILL-Signal (2/INTerrupt, 5/TERMinate-Standard). Alle, müssen Sie tun, ist die PID eines runing scriptB.sh Prozess/Sitzung zu erhalten, sobald scriptB.sh von scriptA.sh genannt wird (nohup ... & werden Sie oder verwenden Sie ps Befehl geben)

trap_mesg() 
{ 
#...do something here for script B.. 
# i.e. 
kill -2 PID_of_ScriptB.sh_running_process_session 
sleep 10; #just in case, not reqd though. 
#show using ps -eAf|grep "scriptB" ... if null means, scriptB is gone. user is happy now. 
#...before actually exiting out... 
#show script A is exiting out as ScriptB is dead already, time for scriptA now. 
#...do something here.. 
} 

##################################### 
## Trap signals : INT, TERM. catch ## 
##################################### 
#Set NULL/Blank value to trap_call. This variable will help in running trap_mesg only once during the life of this script. 
trap_call=""; 

trap 'if [ -z ${trap_call} ]; then trap_call="1"; trap_mesg ; fi' 2 15 
################################## 



Nun, innerhalb von scriptB.sh, tun Sie das gleiche/ähnlich, aber nur für scriptB-Trap-Job (wie das Aufrufen von clean).

clean() 
{ 
echo "karoge seva to milega meva"; 
rm -fr /some/folder_file 
} 

trap_mesg() 
{ 
#...do something here JUST for script B trap message work.. 
# i.e. 
clean; 
#...do something here.. 
} 

##################################### 
## Trap signals : INT, TERM. catch ## 
##################################### 
#Set NULL/Blank value to trap_call. This variable will help in running trap_mesg only once during the life of this script. 
trap_call=""; 

trap 'if [ -z ${trap_call} ]; then trap_call="1"; trap_mesg ; fi' 2 15 
################################## 

Auf diese Weise müssen Sie nicht zu Quelle haben/Call scriptB.sh innerhalb scriptA.sh als "scriptB.sh ...."