Comment obtenir le PID du processus d’arrière-plan?

Je commence un processus d’arrière-plan à partir de mon script shell et je voudrais supprimer ce processus lorsque mon script se termine.

Comment obtenir le PID de ce processus à partir de mon script shell? Autant que je puisse voir la variable $! contient le PID du script en cours, pas le processus en arrière-plan.

Vous devez enregistrer le PID du processus d’arrière-plan au moment où vous le démarrez:

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

Vous ne pouvez pas utiliser le contrôle des travaux, car il s’agit d’une fonction interactive et liée à un terminal de contrôle. Un script n’aura pas forcément de terminal attaché, donc le contrôle des tâches ne sera pas nécessairement disponible.

Vous pouvez utiliser la commande jobs -l pour accéder à 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.

Des help jobs :

-l Indique l’ID du groupe de processus et le répertoire de travail des travaux.

jobs -p est une autre option qui affiche uniquement les PID.

  • $$ est le pid du script actuel
  • $! est le pid du dernier processus de fond

Voici un exemple de transcription d’une session bash ( %1 réfère au nombre ordinal de processus d’arrière-plan vu des jobs ):

 $ echo $$ 3748 $ sleep 100 & [1] 192 $ echo $! 192 $ kill %1 [1]+ Terminated sleep 100 

Un moyen encore plus simple de supprimer tous les processus fils d’un script bash:

 pkill -P $$ 

L’indicateur -P fonctionne de la même manière avec pkill et pgrep – il obtient des processus fils, mais uniquement avec pkill les processus enfants sont pgrep et avec pgrep les PID enfants sont imprimés vers stdout.

c’est ce que j’ai fait. Vérifiez-le, j’espère que cela peut vous 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, lancez-le simplement comme ./bgkill.sh : ./bgkill.sh avec les permissions 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 aussi être capable d’utiliser pstree:

 pstree -p user 

Cela donne généralement une représentation textuelle de tous les processus pour l’utilisateur et l’option -p donne l’identifiant du processus. Pour autant que je sache, cela ne dépend pas de la propriété des processus par le shell actuel. Il montre également des fourchettes.

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

 trap 'kill $( pgrep -P $$ | tr "\n" " " )' SIGINT SIGTERM EXIT