Como obter o pid do último comando executado no shell script?

254

Eu quero ter um script de shell como este:

my-app &
echo $my-app-pid

Mas não sei como obter o pid do comando recém-executado.

Eu sei que posso apenas usar o jobs -p my-appcomando para cumprimentar o pid. Mas se eu quiser executar o shell várias vezes, esse método não funcionará. Porque o jobpec é ambíguo.

David S.
fonte

Respostas:

338

O PID do último comando executado está na $!variável shell:

my-app &
echo $!
enzotib
fonte
1
Está imprimindo pid como por exemplo. [1] 893 Eu quero apenas o número.
User3153014
33
Note-se que isso significa programas iniciados em segundo plano . Se nenhum processo em segundo plano foi iniciado, o parâmetro não está definido.
ramrunner
5
Outra solução digna é sugerido em (um comentário a uma resposta a) Como chegar pid do processo apenas começou : oh, eo "oneliner": /bin/sh -c 'echo $$>/tmp/my.pid && exec program args' &- sysfault 24 '10 novembro às 14:28
IMZ - Ivan Zakharyaschev
14
@ user3153014 Seqüências de caracteres como "[2] 2625" são impressas pelo shell após o início da tarefa em segundo plano. Isto não está relacionado à saída deecho $!
Petr Gladkikh
Normalmente, uso esse código em um script quando preciso aguardar o término do processo. my-app & myVar=$! ; fg. fgtraz o processo para o primeiro plano novamente. Posso imprimir echo $myVarmais tarde e tenho certeza de que o meu aplicativo já terminou.
Vrata Blazek 4/03
66

Obter PID:

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

Salvar PIDna variável:

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

Salve todas as instâncias PIDno arquivo de texto:

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

Salve saída, erros e PIDem arquivos 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
fonte
3
Como a pergunta não foi feita sobre o redirecionamento, sua resposta é basicamente a mesma que a aceita, exceto se uma instância for my-appconcluída e, talvez ainda pior, seu PID seja reutilizado mais tarde, você terá informações ruins em seu arquivo. Eu não acho que esta resposta agregue muito valor à resposta aceita existente, na verdade #
Eric Renouf
Post @EricRenouf atualizado!
Eduardo Cuomo
outro derivado que pode ser útil. Isso obtém o PID e, ao mesmo tempo, trata-o como um processo (principalmente) em primeiro plano: sleep 4 | grep INVALID & export MY_PID=$!; fg; echo $MY_PID returned with $?`
mlathe 26/04/19
não é APP = main &uma maneira de pegar o PID?
MrMesees
3

Tente algo como

pidof my_app >> /tmp/my_app.pid
Piyush Jain
fonte
1
comando externo e lento, se o sistema pode fornecer PID diretamente, por que pesquisar em todos os processos para encontrar exatamente isso? e também, não posso ter certeza de que você obterá o valor correto
papo 02/01
-4

Tente algo como isto:

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

Colocar a primeira letra do seu processo entre [ ]garante que você não consiga o grepprocesso na sua lista. Se necessário, você também pode adicionar um grep ao seu nome de usuário.

Goez
fonte
9
Isso é muito frágil na melhor das hipóteses e não funciona se my-appfor executado mais de uma vez - davidshen84 se preocupa especificamente com esse caso.
Mat
2
Se você seguir esse caminho, use-o pgrep.
Willem