12
votes

Tuer les enfants de premier plan du script de bash lorsqu'un signal vient

Je m'enveloppe une application FastCGI dans un script Bash comme ceci:

#!/bin/bash
# stuff
./fastcgi_bin &
PID=$!
trap "kill $PID" TERM
# stuff


0 commentaires

7 Réponses :


-1
votes

Vous pouvez le faire avec un Coprocess .

EDIT: Eh bien, les coprofessions sont des processus de fond qui peuvent avoir STDIN et STDOUT OUVERT (car BASH prépare des FIFOS pour eux). Mais vous avez toujours besoin de lire / écrire sur ces FIFOS, et la seule primitive utile pour celle-ci est de Bash (éventuellement avec un délai d'attente ou un descripteur de fichier); rien de suffisamment robuste pour un CGI. Donc, à la deuxième pensée, mon conseil ne serait pas de faire cette chose à Bash. Faire le travail supplémentaire dans la FastCGI, ou dans une enveloppe HTTP comme WSGI, serait plus pratique.


0 commentaires

16
votes

Il y a quelques options qui me viennent à l'esprit:

  • Lorsqu'un processus est lancé à partir d'un script shell, tous deux appartiennent au même groupe de processus. Tuer le processus des parents quitte les enfants en vie. L'ensemble du groupe de processus devrait donc être tué. Cela peut être réalisé en passant dans la PGID annulé (ID de groupe de processus) à tuer, ce qui est identique à la PID du parent. EJ: Kill -term - $ parent_pid

  • n'exécute pas le binaire comme un enfant, mais le remplacement du script Processus avec EXEC . Tu perds le capacité à exécuter des choses après cependant, parce que exécuté complètement remplace le processus parent.

  • Ne tuez pas le processus de script shell, mais le binaire FastCGI. Ensuite, dans le script, examinez le code de retour et agissez en conséquence. E.g: ./ fastcgi_bin || EXIT -1

    Selon la façon dont mod_fastcgi gère les processus de travailleurs, seule la deuxième option pourrait être viable.


3 commentaires

C'était aussi ma première pensée: killpg .


exec était exactement ce dont j'avais besoin! Merci


Vous pouvez également envisager d'approfondir l'autre script. Cela lui permet d'exécuter dans le même processus sans éliminer le reste du script actuel. (par exemple. ./fastcgi.bin) (c'est-à-dire <€ Période> )



1
votes

Je ne sais pas si ceci est une option pour vous ou non, mais depuis que vous avez une prime, je suppose que vous pourriez aller pour des idées qui sont en dehors de la boîte.

Pourriez-vous réécrire le script Bash à Perl? Perl a plusieurs méthodes de gestion des processus d'enfants. Vous pouvez lire perldoc perlipc et plus spécifiques dans les modules de base ipc :: open2 et IPC :: open3 .

Je ne sais pas comment cela s'interfacera avec Lightpd, etc. ou s'il y a plus de fonctionnalités dans cette approche, mais au moins cela vous donne une plus grande flexibilité et d'autres à lire dans votre chasse.


0 commentaires

1
votes

Je ne suis pas sûr de bien avoir votre point de vue, mais voici ce que j'ai essayé et que le processus semble être capable de gérer le piège (appelez-le Trap.sh):

./trap.sh


2 commentaires

Kill avec un spécificateur de travail et des signaux de terminal Envoi à l'ensemble du groupe de processus, de sorte que la coque et dorment . Au fait, pourquoi essayez-vous d'attraper sigkill ?


@ Jilles: Assez juste, j'ai édité le message pour correspondre à votre commentaire.



0
votes

Vous pouvez remplacer l'implicite dev / null null null> pour un processus d'arrière-plan en redirection de stdin vous-même, par exemple:

sh -c 'exec 3<&0; { read x; echo "[$x]"; } <&3 3<&- & exec 3<&-; wait'


0 commentaires

1
votes

J'ai écrit ce script il y a quelques minutes pour tuer un script Bash et tous ses enfants ... xxx

Assurez-vous que le script est exécutable, ou vous obtiendrez une erreur sur 0 $ $ i


0 commentaires

0
votes

Essayez de garder l'original stdin à l'aide de ./ fastcgi_bin 0 <& 0 & : xxx


0 commentaires