Wie funktioniert trap / kill in bash unter Linux?

9

Meine Beispieldatei

traptest.sh:

%Vor%

$ traptest.sh & amp;

  
    

[1] 4280

  

$ kill% 1 & lt; - Kill nach Jobnummer funktioniert

  
    

Beendet

         

gefangen

  

$ traptest.sh & amp;

  
    

[1] 4280

  

$ kill 4280 & lt; - kill by process id funktioniert nicht?

  
    

(Sound von Grillen, Prozess wird nicht getötet)

  

Wenn ich die Trap-Anweisung vollständig lösche, funktioniert die Kill-Prozess-ID wieder?

Laufen einige RHEL 2.6.18-194.11.4.el5 bei der Arbeit. Ich bin wirklich verwirrt von diesem Verhalten, ist es richtig?

    
Jason Zavaglia 07.01.2013, 13:59
quelle

3 Antworten

5
%Vor%

sendet das TERM-Signal ausschließlich an die angegebene PID.

%Vor%

Senden Sie das TERM-Signal an die gesamte Prozessgruppe des Jobs # 1, in diesem Fall an das Skript pid + seine Kinder (sleep).

Ich habe das mit strace im Schlafprozess und im Skriptprozess überprüft

Wie auch immer, jemand hat hier ein ähnliches Problem (aber mit SIGINT anstelle von SIGTERM): Ссылка .

Zitieren des wichtigsten Satzes:

kill -INT% 1 sendet das Signal an die Prozessgruppe des Jobs, nicht an die Hintergrund-PID!

    
Davide Berra 07.01.2013, 14:55
quelle
7

Dies ist das erwartete Verhalten. Das von kill gesendete Standard-Signal ist SIGTERM , das Sie von Ihrer Falle fangen. Bedenken Sie Folgendes:

%Vor%

(Schlaf schafft wirklich einen neuen Prozess und das Verhalten ist klarer mit meinem Beispiel, denke ich).

Wenn Sie also traptest.sh in einem Terminal und kill TRAPTEST_PROCESS_ID von einem anderen Terminal ausführen, wird die Ausgabe im Terminal, auf dem der Traptest läuft, wie erwartet Booh! (und der Prozess wird NICHT beendet) . Wenn Sie versuchen, kill -s HUP TRAPTEST_PROCESS_ID zu senden, wird der Traptest-Prozess beendet.

Dies sollte die %1 Verwirrung klären.

Hinweis: Das Codebeispiel stammt aus tldp

    
davak 07.01.2013 14:51
quelle
1

Davide Berra erklärte den Unterschied zwischen kill %<jobspec> und kill <PID> , aber nicht wie dieser Unterschied in dem resultiert, was Sie beobachtet haben. Schließlich sollten Unix-Signal-Handler so ziemlich sofort aufgerufen werden. Warum löst also das Senden eines SIGTERM an das Skript alleine nicht den Trap-Handler aus?

In der >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>^^ Abschnitt :

  

Wenn bash auf den Abschluss eines Befehls wartet und ein Signal für   Deutsch:. Englisch: www.mjfriendship.de/en/index.php?op...39&Itemid=32 Wenn ein Trap gesetzt wurde, wird der Trap erst ausgeführt, wenn der Trap   Befehl wird abgeschlossen.

So wurde das Signal sofort geliefert, aber die Handler-Ausführung wurde zurückgestellt bis bash exited .

Daher mit sleep :

  • Sowohl das Skript als auch kill %<jobspec> erhalten sleep
  • SIGTERM registrierte das Signal, bemerkte, dass ein bash dafür gesetzt wurde, und stellte den Handler für die zukünftige Ausführung in die Warteschlange
  • trap wurde sofort beendet
  • sleep notiert bash beendet und hat den Trap-Handler
  • ausgeführt

wobei mit sleep :

  • Nur das Skript erhielt kill <script_PID>
  • SIGTERM registrierte das Signal, bemerkte, dass ein bash dafür gesetzt wurde, und stellte den Handler für die zukünftige Ausführung in die Warteschlange
  • trap beendet nach 1000 Sekunden
  • sleep notiert bash beendet und hat den Trap-Handler
  • ausgeführt
Natürlich wollten Sie nicht lange genug, um das letzte bisschen zu sehen. :)

Wenn Sie an den blutigen Details interessiert sind, laden Sie den sleep Quellcode herunter und schauen Sie in% co_de nach %, speziell die Funktionen bash und trap.c .

    
Adrian 20.03.2018 07:50
quelle

Tags und Links