Question

NOTE:. Je pensais que j'utilisais bash, mais / bin / sh est lié à / bin / tableau de bord, qui a ce problème bizarre exec

J'ai un simple script shell bash sous Linux qui est utilisé pour lancer un processus serveur (que je n'ai pas écrit ou le contrôle) et je voudrais avoir la sortie de script shell bash PID du processus lancé à un pidfile.

Le problème est que la commande bash-exec ne remplace pas son propre processus avec le processus serveur lancé!

echo $$ | cat > /var/run/launched-server.pid

Cela ne pas parce que le travail pid dans le fichier sera celui de bash pas le processus serveur. Et si les sorties de processus de serveur bash ne peut pas quitter le script sortir de lancement stupide traîner dans la liste des processus.

Quelqu'un sait-il un moyen de bash utilisation de telle sorte que (ou tableau de bord peut-être?):

  1. Est-il possible?
  2. PID du processus serveur-serveur lancé sera dans mon pidfile?
  3. Assurez-vous que le script bash va mourir lorsque le serveur lancé existe et ne pas laisser les processus shell défunte traîner dans la liste des processus?

Edit: Cet extrait de la bash manuel de référence être utile ...

exec
           exec [-cl] [-a name] [command [arguments]]
  

Si la commande est fourni, il remplace le shell sans créer un nouveau processus. Si l'option -l est fournie, la coque place un tableau de bord au début de l'argument passé à la commande zeroth. C'est ce que le programme de connexion fait. Les causes d'option -c commande à exécuter avec un environnement vide. Si -a est fourni, le shell transmet le nom comme argument de commande zeroth. Si aucune commande est spécifiée, les redirections peuvent être utilisés pour influer sur l'environnement du shell en cours. S'il n'y a aucune erreur de redirection, l'état de retour est égal à zéro; sinon le statut de retour est non nul.


Edit 2: Ceci est le script (aseptisé):

#!/bin/sh

# this is where the server expects to run its services for Daemontools
SERVICE_DIR='/var/service';

# kill stdout, stderr, stdin
exec </dev/null
exec >/dev/null
exec 2>/dev/null

logger -ip daemon.debug -- stdout, stderr, stdin redirected to /dev/null

if [ -d $SERVICE_DIR ]; then
    # sanitized...
    logger -ip daemon.debug -- services and supervisors exited
else
    logger -ip daemon.err -- $SERVICE_DIR does not exist, exiting
    exit 1;
fi

if [ -d /var/run/pid ]; then
    echo $$ | cat > /var/run/pid/launched-server.pid
    logger -ip daemon.debug -- creating launched-server pidfile
fi

# start the server process
logger -ip daemon.info -- launching server on $SERVICE_DIR
exec /usr/local/bin/launched-server

Et une sortie ps pour être peut-être plus clair?

me@chainsaw: ~/dev $ ps ax | grep launched-server
13896 pts/1    S+     0:00 /bin/sh ./server_boot
13905 pts/1    S+     0:00 launched-server /var/service
13938 pts/2    R+     0:00 grep --color=auto launched-server
Était-ce utile?

La solution

Est-ce que votre distribution comprend start-stop-daemon(8)? petit outil utile Merveilleusement, il a été construit spécialement pour daemons à partir de scripts shell. (Bien sûr, les daemons vivent plus longtemps que les scripts shell, donc il ne peut pas être un match parfait - cela dépend de la raison pour laquelle vous voulez que le shell survivra votre démon.)

Ou, pour quelque chose de plus simple:

pourrait être résolu votre problème avec la commande exec de bash? Il remplace le processus shell avec ce programme que vous demandez à exécuter:

#!/bin/bash

echo $$ > /tmp/pidfile
exec /bin/sleep 60

$ ./show_exec.sh 
[nothing happens]

Et, dans un autre shell:

$ cat pidfile
24686
$ ps auxw | grep 24686
sarnold  24686  0.0  0.0   9728   816 pts/1    S+   04:53   0:00 /bin/sleep 60

Autres conseils

Je me rends compte maintenant ce que le réel problème était:

En utilisant #!/bin/sh je n'invoquer bash, mais tiret.

exec de Dash est le shell avec le problème exec. Si je l'avais utilisé #!/bin/bash depuis le début, il aurait fonctionné comme prévu.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top