Question

Je commence un processus d'arrière-plan de mon script shell, et je voudrais tuer ce processus se termine quand mon script.

Comment obtenir le PID de ce processus de mon script shell? Pour autant que je peux voir $! variable contient le PID du script en cours, pas le processus d'arrière-plan.

Était-ce utile?

La solution

Vous devez enregistrer le PID du processus d'arrière-plan au moment où vous lancez:

foo &
FOO_PID=$!
# do other stuff
kill $FOO_PID

Vous ne pouvez pas utiliser le contrôle de l'emploi, puisque c'est une fonction interactive et liée à un terminal de contrôle. Un script aura pas nécessairement un terminal connecté à tous si le contrôle de l'emploi ne sera pas forcément disponible.

Autres conseils

Vous pouvez utiliser la commande jobs -l pour arriver à un jobL particulier

^Z
[1]+  Stopped                 guard

my_mac:workspace r$ jobs -l
[1]+ 46841 Suspended: 18           guard

Dans ce cas, 46841 est le PID.

De help jobs:

  

-l rapport, l'ID du groupe de processus et répertoire de travail des emplois.

jobs -p est une autre option qui montre juste le PIDs.

  • $$ est pid du script en cours
  • $! est le pid du dernier processus d'arrière-plan

Voici une transcription de l'échantillon d'une session bash (%1 fait référence au nombre ordinal de processus d'arrière-plan vu de jobs):

$ echo $$
3748

$ sleep 100 &
[1] 192

$ echo $!
192

$ kill %1

[1]+  Terminated              sleep 100

Une façon encore plus simple de tuer tous les processus fils d'un script bash:

pkill -P $$

Le drapeau -P fonctionne de la même manière avec pkill et pgrep -. Il obtient des processus enfants, seulement pkill les processus enfants tués et PIDs enfants de pgrep sont imprimés à stdout

ce que je l'ai fait. Check it out, espérons qu'il peut aider.

#!/bin/bash
#
# So something to show.
echo "UNO" >  UNO.txt
echo "DOS" >  DOS.txt
#
# Initialize Pid List
dPidLst=""
#
# Generate background processes
tail -f UNO.txt&
dPidLst="$dPidLst $!"
tail -f DOS.txt&
dPidLst="$dPidLst $!"
#
# Report process IDs
echo PID=$$
echo dPidLst=$dPidLst
#
# Show process on current shell
ps -f
#
# Start killing background processes from list
for dPid in $dPidLst
do
        echo killing $dPid. Process is still there.
        ps | grep $dPid
        kill $dPid
        ps | grep $dPid
        echo Just ran "'"ps"'" command, $dPid must not show again.
done

Ensuite, exécutez simplement comme: ./bgkill.sh avec des autorisations appropriées bien sûr

root@umsstd22 [P]:~# ./bgkill.sh
PID=23757
dPidLst= 23758 23759
UNO
DOS
UID        PID  PPID  C STIME TTY          TIME CMD
root      3937  3935  0 11:07 pts/5    00:00:00 -bash
root     23757  3937  0 11:55 pts/5    00:00:00 /bin/bash ./bgkill.sh
root     23758 23757  0 11:55 pts/5    00:00:00 tail -f UNO.txt
root     23759 23757  0 11:55 pts/5    00:00:00 tail -f DOS.txt
root     23760 23757  0 11:55 pts/5    00:00:00 ps -f
killing 23758. Process is still there.
23758 pts/5    00:00:00 tail
./bgkill.sh: line 24: 23758 Terminated              tail -f UNO.txt
Just ran 'ps' command, 23758 must not show again.
killing 23759. Process is still there.
23759 pts/5    00:00:00 tail
./bgkill.sh: line 24: 23759 Terminated              tail -f DOS.txt
Just ran 'ps' command, 23759 must not show again.
root@umsstd22 [P]:~# ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
root      3937  3935  0 11:07 pts/5    00:00:00 -bash
root     24200  3937  0 11:56 pts/5    00:00:00 ps -f

Vous pourriez également être en mesure d'utiliser pstree:

pstree -p user

Cela donne généralement une représentation textuelle de tous les processus de l ' « utilisateur » et l'option -p donne le processus id. Il ne dépend pas, pour autant que je comprends, d'avoir les processus appartiendront à l'interpréteur de commandes actuel. Il montre également les fourches.

pgrep peut vous obtenir tous les PIDs enfants d'un processus parent. Comme mentionné précédemment $$ est les scripts actuels PID. Donc, si vous voulez un script qui nettoie après lui-même, cela devrait faire l'affaire:

trap 'kill $( pgrep -P $$ | tr "\n" " " )' SIGINT SIGTERM EXIT
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top