¿Cómo obtener el pid del último comando ejecutado en el script de shell?

254

Quiero tener un script de shell como este:

my-app &
echo $my-app-pid

Pero no sé cómo obtener el pid del comando recién ejecutado.

Sé que puedo usar el jobs -p my-appcomando para grep el pid. Pero si quiero ejecutar el shell varias veces, este método no funcionará. Porque el jobspec es ambiguo.

David S.
fuente

Respuestas:

338

El PID del último comando ejecutado está en la $!variable de shell:

my-app &
echo $!
enzotib
fuente
1
Está imprimiendo pid como por ejemplo. [1] 893. Solo quiero un número.
user3153014
33
Cabe señalar que esto significa programas iniciados en segundo plano . Si no se han iniciado procesos en segundo plano, el parámetro no se establece.
ramrunner
55
Se sugiere otra solución digna en (un comentario a una respuesta a) Cómo obtener el pid del proceso recién iniciado : oh, y el "oneliner": /bin/sh -c 'echo $$>/tmp/my.pid && exec program args' &- sysfault 24 de noviembre de 10 a 14:28
imz - Ivan Zakharyaschev
14
@ user3153014 Las cadenas como "[2] 2625" se imprimen por shell después de iniciar la tarea en segundo plano. Esto no está relacionado con la salida deecho $!
Petr Gladkikh
Usualmente uso dicho código en un script cuando necesito esperar hasta que finalice el proceso. my-app & myVar=$! ; fg. fgtrae el proceso a primer plano de nuevo. Luego puedo imprimir echo $myVarmás tarde y estoy bastante seguro de que mi aplicación ya ha finalizado.
Vrata Blazek
66

Obtener PID:

#!/bin/bash
my-app &
echo $!

Guardar PIDen variable:

#!/bin/bash
my-app &
export APP_PID=$!

Guarde todas las instancias PIDen el archivo de texto:

#!/bin/bash
my-app &
echo $! >>/tmp/my-app.pid

Guardar resultados, errores y PIDen archivos separados:

#!/bin/bash
my-app >/tmp/my-app.log 2>/tmp/my-app.error.log &
echo $! >>/tmp/my-app.pid

echo "my-app PID's: $(cat /tmp/my-app.pid)"
Eduardo Cuomo
fuente
3
La pregunta no se refería a la redirección, entonces su respuesta es casi la misma que la aceptada, excepto que si my-appfinaliza una instancia , y quizás peor aún, su PID se reutiliza más adelante, tendrá información incorrecta en su archivo. No creo que esta respuesta agregue mucho valor a la respuesta aceptada existente realmente
Eric Renouf
¡Publicación de @EricRenouf actualizada!
Eduardo Cuomo
Otra derivada que podría ser útil. Esto obtiene el PID y al mismo tiempo lo trata como un proceso (principalmente) en primer plano: sleep 4 | grep INVALID & export MY_PID=$!; fg; echo $MY_PID returned with $?`
mlathe
¿No es APP = main &una forma de tomar PID?
MrMesees
3

Intenta algo como

pidof my_app >> /tmp/my_app.pid
Piyush Jain
fuente
1
comando externo y lento, si el sistema puede proporcionar PID directamente, ¿por qué buscar en todos los procesos para encontrar exactamente eso? y tampoco puedo estar seguro de que obtendrás el valor correcto
papo
-4

Intenta algo como esto:

 ps ef | grep "[m]y-app" | awk '{print $2}'

Colocar la primera letra de su proceso entre [ ]se asegura de que no obtenga el grepproceso en su lista. Si es necesario, también puede agregar un grep a su nombre de usuario.

Dios
fuente
99
Eso es muy frágil en el mejor de los casos y no funciona si my-appse ejecuta más de una vez; davidshen84 se preocupa específicamente por ese cas.
Mat
2
Si incluso sigue esta ruta, debería usarla pgrepen su lugar.
Willem