Come ottenere il pid dell'ultimo comando eseguito nello script della shell?


254

Voglio avere uno script di shell come questo:

my-app &
echo $my-app-pid

Ma non so come ottenere il pid del comando appena eseguito.

So che posso semplicemente usare il jobs -p my-appcomando per grep il pid. Ma se voglio eseguire la shell più volte, questo metodo non funzionerà. Perché il jobspec è ambiguo.

Risposte:


338

Il PID dell'ultimo comando eseguito è nella $!variabile shell:

my-app &
echo $!

1
Stampa pid come per es. [1] 893. Voglio solo un numero.
— user3153014

33
Va notato che ciò significa programmi avviati in background . Se non sono stati avviati processi in background, il parametro non è impostato.
— Ramrunner,

5
Un'altra soluzione degna è suggerita in (un commento a una risposta a) Come ottenere il pid del processo appena iniziato : oh, e "oneliner": /bin/sh -c 'echo $$>/tmp/my.pid && exec program args' &- sysfault 24 novembre 10 alle 14:28
— imz - Ivan Zakharyaschev

14
@ user3153014 Le stringhe come "[2] 2625" vengono stampate dalla shell dopo aver avviato l'attività in background. Questo non è correlato alla produzione diecho $!
— Petr Gladkikh,

Di solito uso tale codice in uno script quando devo aspettare fino al termine del processo. my-app & myVar=$! ; fg. fgporta di nuovo in primo piano il processo. Posso quindi stampare echo $myVarpiù tardi e sono abbastanza sicuro che la mia app sia già terminata.
— Vrata Blazek,

66

Ottieni PID:

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

Salva PIDin variabile:

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

Salva tutte le istanze PIDnel file di testo:

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

Salva output, errori e PIDin file separati:

#!/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)"

3
La domanda non si poneva sul reindirizzamento, quindi la tua risposta è sostanzialmente la stessa di quella accettata, tranne per il fatto che se un'istanza my-apptermina, e forse anche peggio, il suo PID viene riutilizzato in seguito, avrai informazioni errate nel tuo file. Non credo che questa risposta aggiunga molto valore alla risposta accettata esistente davvero
— Eric Renouf,

Post @EricRenouf aggiornato!
— Eduardo Cuomo,

un altro derivato che potrebbe essere utile. Questo ottiene il PID e allo stesso tempo lo tratta come un processo (principalmente) in primo piano: sleep 4 | grep INVALID & export MY_PID=$!; fg; echo $MY_PID returned with $?`
— ml

isnt APP = main &un modo per afferrare il PID?
— MrMesees,

3

Prova qualcosa del genere

pidof my_app >> /tmp/my_app.pid

1
comando esterno e lento, se il sistema può fornire direttamente il PID perché cercare in tutti i processi per trovare proprio quello? e inoltre, non posso essere certo che otterrai il valore corretto
— papo

-4

Prova qualcosa del genere:

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

Posizionando la prima lettera del processo tra [ ]si assicura che non si ottiene il grepprocesso nell'elenco. Se necessario, puoi anche aggiungere un grep al tuo nome utente.


9
Nella migliore delle ipotesi è molto fragile e non funziona se my-appviene eseguito più di una volta - davidshen84 si preoccupa specificamente di quel cas.
— Mat

2
Se segui anche questa strada, dovresti usare pgrepinvece.
— Willem,
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.