¿Por qué $$ devuelve la misma identificación que el proceso padre?

160

Tengo un problema con Bash y no sé por qué.
Debajo de la concha, entro:

echo $$    ## print 2433
(echo $$)  ## also print 2433
(./getpid) ## print 2602

"getpid" es un programa en C para obtener pid actual, como:

   int main() {
    printf("%d", (int)getpid());
    return 0;
   }

Lo que me confunde es que:

  1. Creo que "(comando)" es un subproceso (¿estoy en lo cierto?), Y creo que su pid debería ser diferente con su padre pid, pero son lo mismo, por qué ...
  2. cuando uso mi programa para mostrar pid entre paréntesis, el pid que muestra es diferente, ¿es correcto?
  3. ¿Es '$$' algo así como macro?

¿Me puedes ayudar?

ruanhao
fuente
8
Tenga en cuenta que getpidmostraría una ID de proceso diferente incluso si no se ejecutara en una subshell.
chepner
1
@ Marian echo $$ $BASHPID ; ( echo $$ $BASHPID )demuestra que sí. Los corchetes crean una subshell. Las declaraciones pueden cambiar los valores de las variables y el shell principal no debe ver esos cambios. Esto se implementa como una fork()operación.
Ben

Respuestas:

223

$$se define para devolver el ID de proceso del padre en una subshell; de la página del manual bajo "Parámetros especiales":

$ Se expande al ID de proceso del shell. En un subshell (), se expande al ID del proceso del shell actual, no al subshell.

En bash4, puede obtener el ID de proceso del niño con BASHPID.

~ $ echo $$
17601
~ $ ( echo $$; echo $BASHPID )
17601
17634
chepner
fuente
17
"padre" es un poco engañoso (al menos para mí), en realidad es el caparazón de "nivel superior". Por ejemplo: echo $$; (echo $$; (echo $$))repite el mismo pedido tres veces
Martin Bouladour
1
Correcto; Debería haber dicho que el valor se hereda de un shell padre (que hereda su valor de su padre, etc.). El shell de nivel superior lo establece inicialmente, en lugar de heredar de su proceso padre (no shell).
chepner
$ Expands to the process ID of the shelllo hace? echo $solo hace eco del literal $.
Alexander Mills
@AlexanderMills Bueno, sí; $solo no es una expansión de parámetros. La página del manual se refiere al nombre del parámetro especial, que es $; no dice que $solo se expanda.
chepner
Ok, sinceramente, no tengo idea de lo que eso significa, pero echo $BASHPIDfunciona en bash 4 y 5 (pero no en la versión 3.2.57 en MacOS)
Alexander Mills
81

Puede usar uno de los siguientes.

  • $! es el PID del último proceso en segundo plano.
  • kill -0 $PID comprueba si aún se está ejecutando.
  • $$ es el PID del shell actual.
agrietado
fuente
2
¿No debería ser la segunda viñeta kill -0 $!si estamos hablando de procesos en segundo plano? PIDno está configurado en nada de forma predeterminada.
Isaac Freeman
26
  1. Los paréntesis invocan una subshell en Bash . Dado que es solo una subshell, puede tener el mismo PID, depende de la implementación.
  2. El programa C que invocas es un proceso separado, que tiene su propio PID único, no importa si está en una subcapa o no.
  3. $$es un alias en Bash para el script PID actual . Vea las diferencias entre $$y $BASHPIDaquí , y justo encima de esa variable adicional $BASH_SUBSHELLque contiene el nivel de anidamiento.
Niels Keurentjes
fuente
4

Pruebe getppid()si desea que su programa C imprima el PID de su shell.

Alex
fuente
2

Si estuviera preguntando cómo obtener el PID de un comando conocido, se parecería a algo como esto:

Si emitió el comando a continuación #El comando emitido fue ***

dd if = / dev / diskx of = / dev / disky


Entonces usarías:

PIDs=$(ps | grep dd | grep if | cut -b 1-5)

Lo que sucede aquí es que canaliza todos los caracteres únicos necesarios a un campo y ese campo puede repetirse usando

echo $ PID

Don-Pierre Halfaway
fuente
2

Esta es una forma universal de obtener el pid correcto

pid=$(cut -d' ' -f4 < /proc/self/stat)

mismo bien trabajado para sub

SUB(){
    pid=$(cut -d' ' -f4 < /proc/self/stat)
    echo "$$ != $pid"
}

echo "pid = $$"

(SUB)

verificar salida

pid = 8099
8099 != 8100
ARTEM LAPKIN
fuente
Buena idea, pero ¿no te dará el pid de la bifurcación que el shell ha ejecutado para capturar la salida de corte? Si lo ejecuto dos veces, una con echo $ (...) y otra sin, obtengo diferentes respuestas.
Martin Dorey