Comment obtenir PID du processus d'arrière-plan?
-
19-09-2019 - |
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.
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