Comienzo un proceso en segundo plano desde mi script de shell, y me gustaría eliminar este proceso cuando finalice mi script.
¿Cómo obtener el PID de este proceso desde mi script de shell? Por lo que puedo ver, la variable $!
contiene el PID del script actual, no el proceso en segundo plano.
linux
shell
background-process
pid
Volodymyr Bezuglyy
fuente
fuente
Respuestas:
Debe guardar el PID del proceso en segundo plano en el momento en que lo inicia:
No puede usar el control de trabajos, ya que es una función interactiva y está vinculada a un terminal de control. Un script no necesariamente tendrá un terminal conectado, por lo que el control del trabajo no estará necesariamente disponible.
fuente
foo
y$!
, y obtengamos ese algo pid en lugar defoo
's?foo
resulta que son múltiples comandos canalizados (por ejemplotail -f somefile.txt | grep sometext
). En tales casos, obtendrá el PID del comando grep en$!
lugar del comando tail si eso es lo que estaba buscando. Deberá usarjobs
o meps
gusta en esta instancia.grep
, pero si mata eso, la cola obtendrá un SIGPIPE cuando intente escribir en la tubería. Pero tan pronto como intente entrar en cualquier gestión / control de proceso complicado, bash / shell se vuelve bastante doloroso./bin/sh -c 'echo $$>/tmp/my.pid && exec program args' &
- sysfault 24 de noviembre de 10 a 14:28Puede usar el
jobs -l
comando para llegar a un trabajo en particular.En este caso, 46841 es el PID.
De
help jobs
:jobs -p
es otra opción que muestra solo los PID.fuente
$!
justo después de comenzar es más portátil y más sencillo en la mayoría de las situaciones. Eso es lo que hace la respuesta actualmente aceptada.jobs -p
devuelto lo mismo quejobs -l
en Lubuntu 16.4$$
es el pid del script actual$!
es el pid del último proceso en segundo planoAquí hay una transcripción de muestra de una sesión bash (se
%1
refiere al número ordinal del proceso de fondo como se ve desdejobs
):fuente
%1
no devuelve el proceso en segundo plano en mi Ubuntu mientras que loecho $!
haceUna forma aún más simple de eliminar todos los procesos secundarios de un script bash:
El
-P
indicador funciona de la misma manera conpkill
ypgrep
: obtiene procesos secundarios, solo cuandopkill
los procesospgrep
secundarios se eliminan y con los PID secundarios se imprimen en stdout.fuente
bash -c 'bash -c "sleep 300 &"' &
correrpgrep -P $$
no muestra nada, porque el sueño no será un hijo directo de tu caparazón.$$
refiere al shell actual.bash -c 'bash -c "sleep 300 &"' & ; pgrep -P $$
, me pongo en stdout[1] <pid>. So at least it shows something, but this is probably not the output of
pgrep`bash -c 'bash -c "sleep 10 & wait $!"' & sleep 0.1; pstree -p $$
Esto es lo que he hecho. Compruébalo, espero que pueda ayudarte.
Luego, ejecútelo como:
./bgkill.sh
con los permisos adecuados, por supuestofuente
También puede usar pstree:
Normalmente, esto proporciona una representación de texto de todos los procesos para el "usuario" y la opción -p proporciona la identificación del proceso. No depende, por lo que entiendo, de que los procesos sean propiedad del shell actual. También muestra tenedores.
fuente
pgrep
puede obtener todos los PID secundarios de un proceso principal. Como se mencionó anteriormente, se$$
encuentran los scripts actuales PID. Entonces, si desea un script que se limpie después de sí mismo, esto debería hacer el truco:fuente
trap 'pkill -P $$' SIGING SIGTERM EXIT
Parece más simple, pero no lo probé.SIG
prefijo. POSIX lo permite, pero solo como una extensión que las implementaciones pueden admitir: pubs.opengroup.org/onlinepubs/007904975/utilities/trap.html El shell del guión, por ejemplo, no.