Perché $$ restituisce lo stesso ID del processo padre?


160

Ho un problema con Bash e non so perché.
Sotto shell, entro:

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

"getpid" è un programma C per ottenere il pid corrente, come:

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

Ciò che mi confonde è che:

  1. Penso che "(comando)" sia un sottoprocesso (ho ragione?), E penso che il suo pid dovrebbe essere diverso dal pid genitore, ma sono gli stessi, perché ...
  2. quando uso il mio programma per mostrare il pid tra parentesi, il pid che mostra è diverso, giusto?
  3. '$$' è qualcosa come macro?

Mi potete aiutare?


8
Si noti che getpidmostrerebbe un ID processo diverso anche se non fosse eseguito in una subshell.
Chepner,

1
@Marian lo echo $$ $BASHPID ; ( echo $$ $BASHPID )dimostra. Le parentesi tonde creano una subshell. Le istruzioni possono modificare i valori delle variabili e la shell padre non deve vedere tali modifiche. Questo è implementato come fork()un'operazione.
Ben

Risposte:


223

$$è definito per restituire l'ID di processo del genitore in una subshell; dalla pagina man sotto "Parametri speciali":

$ Si espande nell'ID del processo della shell. In una subshell (), si espande nell'ID del processo della shell corrente, non nella subshell.

In bash4, è possibile ottenere l'ID processo del bambino con BASHPID.

~ $ echo $$
17601
~ $ ( echo $$; echo $BASHPID )
17601
17634

17
"parent" è un po 'fuorviante (almeno lo era per me), in realtà è la shell di "livello superiore". Ad esempio: echo $$; (echo $$; (echo $$))riecheggia lo stesso pid tre volte
Martin Bouladour,

1
Destra; Avrei dovuto dire che il valore è ereditato da una shell genitore (che ha ereditato il suo valore dal suo genitore, ecc.). La shell di livello superiore la imposta inizialmente, piuttosto che ereditare dal suo processo genitore (non shell).
Chepner,

$ Expands to the process ID of the shellvero? echo $fa solo eco al letterale $.
Alexander Mills

@AlexanderMills Bene, sì; $da solo non è un'espansione dei parametri. La pagina man si riferisce al nome del parametro speciale, che è $; non sta sostenendo che $solo si espande.
Chepner

Ok, onestamente non ho idea di cosa significhi, ma echo $BASHPIDfunziona nella bash 4 e 5 (ma non nella versione 3.2.57 su MacOS)
Alexander Mills,

81

È possibile utilizzare uno dei seguenti.

  • $! è il PID dell'ultimo processo in background.
  • kill -0 $PID controlla se è ancora in esecuzione.
  • $$ è il PID della shell corrente.

2
Il secondo punto non dovrebbe essere kill -0 $!se stiamo parlando di processi in background? PIDnon è impostato su nulla per impostazione predefinita.
Isaac Freeman,

26
  1. Le parentesi invocano una subshell in Bash . Poiché è solo una subshell, potrebbe avere lo stesso PID - dipende dall'implementazione.
  2. Il programma C che invochi è un processo separato, che ha il suo PID unico - non importa se si trova in una subshell o no.
  3. $$è un alias in Bash allo script PID corrente . Vedi le differenze tra $$e $BASHPIDqui e proprio sopra quella della variabile aggiuntiva $BASH_SUBSHELLche contiene il livello di annidamento.

4

Prova getppid()se vuoi che il tuo programma C stampi il PID della tua shell.


2

Se chiedessi come ottenere il PID di un comando noto, sarebbe simile a questo:

Se fosse stato emesso il comando seguente # Il comando emesso era ***

dd if = / dev / diskx di = / dev / disky


Quindi useresti:

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

Quello che succede qui è che convoglia tutti i caratteri univoci necessari in un campo e quel campo può essere ripetuto usando

echo $ PIDs


2

questo modo univoco per ottenere il pid corretto

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

stesso bello ha funzionato per il sub

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

echo "pid = $$"

(SUB)

controlla l'output

pid = 8099
8099 != 8100

Bella idea, ma questo non ti procurerà il pid della forcella che la shell ha eseguito per catturare l'output del taglio? Se lo eseguo due volte, una volta con echo $ (...) e una volta senza, ottengo risposte diverse.
Martin Dorey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.