GNU/Linux >> Tutoriales Linux >  >> Linux

Cómo obtener pid del proceso recién iniciado

Solución 1:

¿Qué puede ser más simple que echo $!? ? Como una línea:

myCommand & echo $!

Solución 2:

Puedes usar sh -c y exec para obtener el PID del comando incluso antes funciona.

Para empezar myCommand , para que su PID se imprima antes de que comience a ejecutarse, puede usar:

sh -c 'echo $$; exec myCommand'

Cómo funciona:

Esto inicia un nuevo shell, imprime el PID de ese shell y luego usa el exec integrado para reemplazar el shell con su comando, asegurándose de que tenga el mismo PID. Cuando su shell ejecuta un comando con el exec incorporado, su caparazón en realidad se está convirtiendo ese comando, en lugar del comportamiento más común de bifurcar una nueva copia de sí mismo, que tiene su propio PID separado y que luego se convierte en el comando.

Encuentro que esto es mucho más simple que las alternativas que involucran la ejecución asíncrona (con & ), control de trabajo o búsqueda con ps . Esos enfoques están bien, pero a menos que tenga una razón específica para usarlos, por ejemplo, tal vez el comando ya se esté ejecutando, en cuyo caso tendría sentido buscar su PID o usar el control de trabajo, sugiero considerar esta manera primero. (Y ciertamente no consideraría escribir un script complejo u otro programa para lograr esto).

Esta respuesta incluye un ejemplo de esta técnica.

Ocasionalmente, se pueden omitir partes de ese comando, pero no por lo general.

Incluso si el shell que está utilizando es de estilo Bourne y, por lo tanto, es compatible con exec integrado con esta semántica, por lo general no debería intentar evitar el uso de sh -c (o equivalente) para crear un nuevo, separado proceso de shell para este propósito, porque:

  • Una vez que el caparazón se haya convertido en myCommand , no hay shell esperando para ejecutar comandos posteriores. sh -c 'echo $$; exec myCommand; foo no podría intentar ejecutar foo después de reemplazarse a sí mismo con myCommand . A menos que esté escribiendo un script que ejecute esto como su último comando, no puede simplemente usar echo $$; exec myCommand en un shell donde está ejecutando otros comandos.
  • No puede usar una subcapa para esto. (echo $$; exec myCommand) puede ser sintácticamente mejor que sh -c 'echo $$; exec myCommand' , pero cuando ejecutas $$ dentro de ( ) , proporciona el PID del shell principal, no del subshell en sí. Pero es el PID de la subcapa el que será el PID del nuevo comando. Algunos shells proporcionan sus propios mecanismos no portátiles para encontrar el PID del subshell, que podría usar para esto. En particular, en Bash 4, (echo $BASHPID; exec myCommand) funciona.

Finalmente, tenga en cuenta que algunos shells realizarán una optimización en la que ejecutarán un comando como si fuera exec (es decir, renuncian a bifurcar primero) cuando se sabe que el caparazón no necesitará hacer nada después. Algunos shells intentan hacer esto cada vez que es el último comando que se ejecutará, mientras que otros solo lo harán cuando no haya otros comandos antes o después del comando, y otros no lo harán en absoluto. El efecto es que si te olvidas de escribir exec y solo usa sh -c 'echo $$; myCommand' entonces lo hará a veces darte el PID correcto en algunos sistemas con algunos conchas Recomiendo no confiar nunca en ese comportamiento y, en su lugar, incluir siempre exec cuando eso es lo que necesitas.

Solución 3:

Envuelva el comando en un pequeño script

#!/bin/bash
yourcommand &
echo $! >/path/to/pid.file

Solución 4:

No conozco ninguna solución más simple, ¡pero no está usando $! ¿suficientemente bueno? Siempre puede asignar el valor a alguna otra variable si lo necesita más adelante, como dicen otros.

Como nota al margen, en lugar de canalizar desde ps, podría usar pgrep o pidof .

Solución 5:

use exec desde un script bash después de registrar el pid en un archivo:

ejemplo:

supongamos que tiene un script llamado "forever.sh" que desea ejecutar con argumentos p1,p2,p3

forever.sh código fuente:

#!/bin/sh

while [ 1 -lt 2 ] ; do
    logger "$0 running with parameters \"[email protected]\""
    sleep 5
done

crear un segador.sh:

#!/bin/sh

echo $$ > /var/run/$1.pid
exec "[email protected]"

ejecute forever.sh a través de reaper.sh:

./reaper.sh ./forever.sh p1 p2 p3 p4 &

forever.sh no hace nada más que registrar una línea en syslog cada 5 segundos

ahora tienes el pid en /var/run/forever.sh.pid

cat /var/run/forever.sh.pid 
5780

y forever.sh está funcionando bien. grep de registro del sistema:

Nov 24 16:07:17 pinkpony cia: ./forever.sh running with parameters "p1 p2 p3 p4"

puedes verlo en la tabla de procesos:

ps axuwww|grep 'forever.sh p1' |grep -v grep
root      5780  0.0  0.0   4148   624 pts/7    S    16:07   0:00 /bin/sh ./forever.sh p1 p2 p3 p4

Linux
  1. ¿Cómo empezar con Juju?

  2. Cómo comenzar con un servidor en la nube de FreeBSD

  3. ¿Obtener programáticamente el id principal de otro proceso?

  4. Cómo obtener un proceso secundario del proceso principal

  5. ¿Cómo obtener el pid de un proceso e invocar kill -9 en el script de shell?

¿Cómo identificar un proceso que no tiene Pid?

Lxc y cómo empezar?

Cómo encontrar el nombre del proceso a partir de su PID

Cómo comenzar con Arch Linux

Cómo comenzar con Midnight Commander en 2022

¿Cómo obtener el PID principal de un proceso determinado en GNU/Linux desde la línea de comandos?