2013-05-14 6 views
1

J'ai un script dans bash pour démarrer un programme java et je veux obtenir le pid du programme après son exécution. Le pid sera sauvegardé dans un fichier texte.Bash: Obtenir le pid d'un processus en utilisant un autre utilisateur

En ce moment, j'ai quelque chose comme ceci:

if [ "$USER" == "root" ] 
then 
    su $APP_USER -c "nohup java $JAVA_OPTS >> $LOG_OUT 2>> $LOG_ERR &" 
    su $APP_USER -c "echo $! > $PID_PATH/$CAT.pid" 
else 
    nohup java $JAVA_OPTS >> $LOG_OUT 2>> $LOG_ERR & 
    echo $! > "$PID_PATH/$CAT.pid" 
fi 

J'ai aussi essayé comme ça, mais ça ne marche pas non plus.

if [ "$USER" == "root" ] 
then 
    su $APP_USER -c "(nohup java $JAVA_OPTS >> $LOG_OUT 2>> $LOG_ERR &); (echo $! > $PID_PATH/$CAT.pid)" 
else 
    nohup java $JAVA_OPTS >> $LOG_OUT 2>> $LOG_ERR & 
    echo $! > "$PID_PATH/$CAT.pid" 
fi 

quand je lance mon APP_USER tout fonctionne très bien, quand je lance en tant que root mon programme java démarre mais le fichier pid est créé vide.

Répondre

4

essayer

su $APP_USER -c "nohup java $JAVA_OPTS >> $LOG_OUT 2>> $LOG_ERR & echo \$! > $PID_PATH/$CAT.pid" 

\ derrière $! empêche l'expansion de la variable, avant de passer à la commande su.

+0

Cette commande fonctionne, mais le fichier est vide. Je ne comprends pas le pid. – fabio

+0

Numéro trouvé ... mis à jour .. Vérifier maintenant .. – anishsane

+0

Ça marche !! : D Tu étais rigth, 'echo' donnait une chaîne vide. C'est pourquoi le fichier pid était vide. – fabio

1

Le problème est que chaque commande su est un appel distinct de l'utilisateur, donc $! ne stockera pas votre dernier PID puisqu'il n'y en a pas.

Ce que vous devez faire est d'enregistrer votre PID dans le même appel que le premier su. La meilleure façon de faire est plus facile de mettre entre guillemets les commandes et les séparer par un point-virgule

su $APP_USER -c "nohup java $JAVA_OPTS >> $LOG_OUT 2>> $LOG_ERR &; "echo $! > $PID_PATH/$CAT.pid" 

Maintenant su invoquera les deux commandes dans le même environnement.

+0

Il est logique, j'essaie votre commande, il donne une erreur sintax, mais il peut être corrigé en utilisant(). 'su $ APP_USER -c" (nohup java $ JAVA_OPTS >> $ LOG_OUT 2 >> $ LOG_ERR &); (echo $!> $ PID_PATH/$ CAT.pid) "' mais je reçois toujours un fichier vide avec pas de pid. – fabio

+0

L'utilisation de '(...)' exécute la commande dans un sous-shell. Puisque vous mettez 'echo $!' Dans un sous-shell séparé, il n'aura pas le PID de la commande précédente. N'utilisez pas '(...)' ou ne placez pas les deux ensembles de commandes dans le même '(...)'. Vous pouvez également essayer des accolades comme '{...}'. Cela exécute votre commande dans le même shell (mais vous devez terminer avec ';') –

+0

J'ai eu un problème avec '&;' à la fin de la première déclaration. Je n'avais pas besoin du ';'. Les '(...)' semblent le résoudre ... mais j'ai besoin d'échapper le '$!' -> '\ $!'. il fonctionne comme ceci: 'su $ APP_USER -c" nohup java $ JAVA_OPTS >> $ LOG_OUT 2 >> $ LOG_ERR & echo \ $!> $ PID_PATH/$ CAT.pid "' Réservoirs pour vos commentaires. :) – fabio

1

Si votre système fournit start-stop-daemon, il peut être plus facile à utiliser que de créer des wrappers fous. Par défaut, vous obtenez le changement d'utilisateur (--user) et le comportement nohup (--background). En outre, vous pouvez utiliser --make-pidfile qui fera la bonne chose - que vous changiez d'utilisateur ou non.

+0

Bonjour, cela semble intéressant, mais je pense que mon SO ne supporte pas cela. Peut-être un besoin d'installer quelque chose de nouveau. Je suis nouveau dans le script bash, cela a quelque chose à voir avec le fonctionnement de 'su -c" command "'. Je ferai d'autres recherches. Réservoirs pour vos commentaires. – fabio

Questions connexes