Pregunta

comienzo a un proceso de fondo de mi script de shell, y me gustaría matar a este proceso cuando termina mi guión.

Cómo obtener el PID de este proceso de mi script? Por lo que yo puedo ver $! variable contiene el PID del script actual, no el proceso en segundo plano.

¿Fue útil?

Solución

Es necesario para salvar el PID del proceso en segundo plano en el momento de empezar a él:

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

No se puede utilizar el control de trabajos, ya que es una función interactiva y atado a un terminal de control. Un script no necesariamente tiene un terminal conectado en absoluto por lo que el control de trabajos no necesariamente va a estar disponible.

Otros consejos

Puede utilizar el comando jobs -l para llegar a un determinado jobL

^Z
[1]+  Stopped                 guard

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

En este caso, 46841 es el PID.

De help jobs:

  

-l El informe de los ID de grupo y el directorio de trabajo de los puestos de trabajo.

jobs -p es otra opción que muestra sólo el PID.

  • $$ es pid del script actual
  • $! es el PID del último proceso en segundo plano

Aquí está una transcripción muestra de una sesión de bash (%1 se refiere al número de orden de proceso de fondo como se ve desde jobs):

$ echo $$
3748

$ sleep 100 &
[1] 192

$ echo $!
192

$ kill %1

[1]+  Terminated              sleep 100

Una forma aún más simple para matar a todos los niños de un proceso de escritura del golpe:

pkill -P $$

La bandera -P funciona de la misma manera con pkill y pgrep -. Se pone procesos hijos, sólo que con pkill los procesos hijos mueren y con los niños PID pgrep se imprimen por la salida estándar

Esto es lo que he hecho. Compruébelo usted mismo, espero que pueda ayudar.

#!/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

A continuación, sólo ejecutarlo como: ./bgkill.sh con los permisos adecuados de curso

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

También puede ser capaz de utilizar pstree:

pstree -p user

Esto normalmente da una representación de texto de todos los procesos para el "usuario" y la opción -p da el proceso de identificación. No depende, por lo que yo entiendo, en tener los procesos de ser propiedad de la shell actual. También muestra horquillas.

pgrep puede conseguir que todos los niños PID de un proceso padre. Como se ha mencionado anteriormente es $$ los guiones actuales PID. Por lo tanto, si quieres un script que limpia después de sí mismo, esto debería hacer el truco:

trap 'kill $( pgrep -P $$ | tr "\n" " " )' SIGINT SIGTERM EXIT
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top