2009-04-03 5 views
5

Nous voulons construire un script qui s'exécute tous les soirs (tue et redémarre un processus Java). Pour cela, nous devons capturer le numéro de processus (car il pourrait y avoir plus d'un processus Java en cours d'exécution). La commande ci-dessous est essentiellement ce que nous allons utiliser pour obtenir le nombre de processus, probablement avec une regexp à la fin du grep. Sauf si de meilleures suggestions apparaissent.Comment capturer le résultat d'un appel système dans une variable shell?

root#ps -e |grep 'java' 
18179 pts/0 00:00:43 java 

Nous voulons savoir comment analyser la sortie ci-dessus et l'obtenir dans une variable shell afin que nous puissions utiliser la commande kill comme ci-dessous.

kill -9 ${processid} 
wait 10 

Note1: La raison pour laquelle nous ne pouvons pas compter sur la commande d'arrêt de service normal est parce que les processus parfois ne veulent pas mourir. Et nous devons utiliser la commande kill manuellement.

+0

Qu'en est-il de pkill? –

Répondre

4

Il y a deux options pour résoudre ce problème. Si vous utilisez bash, alors la variable shell '$!' contiendra le PID du dernier processus enfant forké. Donc, une fois que vous démarrez votre programme Java, faire quelque chose comme:

echo $! > /var/run/my-process.pid 

Puis, après votre script d'initialisation arrête le processus Java:

# Get the pidfile. 
pid=$(cat /var/run/my-process.pid) 

# Wait ten seconds to stop our process. 
for count in $(1 2 3 4 5 6 7 8 9 10); do 
    sleep 1 
    cat "/proc/$pid/cmdline" 2>/dev/null | grep -q java 
    test $? -ne 0 && pid="" && break 
done 

# If we haven't stopped, kill the process. 
if [ ! -z "$pid" ]; then 
    echo "Not stopping; terminating with extreme prejudice." 
    kill -9 $pid 
fi 

Assurez-vous de retirer le pidfile lorsque vous avez terminé.

+1

"Prejucide"? Est-ce une blague ou une faute de frappe? –

+0

C'est ce qui arrive quand je poste une réponse avant le café du matin. –

+0

De plus, si vous avez la commande 'seq', vous pouvez faire 'seq 1 10' au lieu du compte manuel. Cependant, il n'est pas toujours disponible sur toutes les versions de Linux. –

0

tuer:

ps -e | grep java | cut -f1 -d' ' | xargs kill -9 

stockage PID variable:

export JAVAPID=`ps -e | grep 'java' | cut -f1 -d' '` 

vérifier que cela a fonctionné:

echo $JAVAPID 
3
ps aux | grep java | awk '{print $1}' | xargs kill -9 

est ici une explication:

ps aux vous donne une liste de tous les processus

grep java vous donne tous les processus dont les noms et les arguments de ligne de commande contient la chaîne « java »

awk '{print $1}' analyse la sortie de la commande grep en colonnes par espaces et ne réimprime que la première colonne

xargs kill -9 passe chacun des résultats de la commande awk en tant que paramètres à une commande kill -9

+2

Passer le grep: ps aux | awk '/ java/{print $ 1}' :) – andri

+0

Merci pour le conseil; Je ne connais pas assez awk pour savoir comment faire ça. Je vais laisser ma réponse telle qu'elle est parce que c'est plus simple pour moi de comprendre personnellement, mais je suis heureux que vous ayez fait cette suggestion. –

+1

Ne devriez-vous pas avoir un grep -v grep pour l'empêcher de collecter le pid de grep (puisque sa ligne de commande contient le mot java)? –

1

Vous pouvez facilement obtenir le PID ou une liste de PID dans une variable en utilisant les backticks et coupé (ou awk si l'on préfère) pour récupérer uniquement le champ PID:

[[email protected] ~]$ ps -e | grep java | cut -d' ' -f1 
12812 
12870 
13008 
13042 
13060 

Remarque dans l'exemple ci-dessus j'ai plusieurs processus Java s'exécutant d'où les multiples valeurs.Si vous enregistrez cela dans une variable comme ceci:

JAVA_PROCS=`ps -e | grep java | cut -d' ' -f1` 

Vous pouvez parcourir les processus de les tuer si on le désire: si vous ne récupérer un processus

for proc in $JAVA_PROCS; do 
    kill -9 $proc; 
done 

Bien sûr, alors il y a pas besoin de itérer et vous pouvez simplement l'exécuter comme:

kill -9 $JAVA_PROCS 
1

Si vous faites ce que vous proposez, vous pouvez finir par capturer le grep lui-même et tuer que (depuis votre commande grep contient la chaîne java que vous ar e recherchant). Vous pouvez contourner ce problème en excluant grep (en utilisant un autre grep!):

pid=`ps -e | fgrep java | fgrep -v grep | awk '{print $1}'` 
# check pid has a value 
# kill $pid 

Vous aimerez également ps -e -opid,args.

Une meilleure alternative est d'utiliser pgrep(1) ou pkill(1) si votre système en a. Plus de tuyaux, seds, awks, coupes, xargs:

pkill -9 java 
+0

J'ai presque posté la même chose, mais ps -e ne liste pas les arguments cmd (au moins sur ma boîte) donc il n'y a aucun risque de capturer accidentellement la commande 'grep java' dans la sortie grep. – Jay

+0

Spot sur, Jay, au moins pour Linux. Je préfère encore pkill mais on dirait que je suis en minorité. –

+0

Vous pouvez également coller des parenthèses autour du premier caractère dans le grep, comme dans grep [j] ava Le grep le voit comme une regex et cherche un j, mais la ligne de commande ne correspondra pas au motif. :) Ca me fait me sentir sale quand je le fais, mais ça marche bien ... – dannysauer

0

-je utiliser quelque chose comme ceci:

kill $(ps -A | grep java | cut -b 1-5) 
2

Je sais que c'est vieux, mais qu'en est-:

pidof java | xargs kill 
Questions connexes