Jak uzyskać pid ostatniego wykonanego polecenia w skrypcie powłoki?


254

Chcę mieć taki skrypt powłoki:

my-app &
echo $my-app-pid

Ale nie wiem, jak uzyskać pid właśnie wykonanego polecenia.

Wiem, że mogę po prostu użyć jobs -p my-apppolecenia, aby grep pid. Ale jeśli chcę uruchomić powłokę wiele razy, ta metoda nie będzie działać. Ponieważ rodzaj zadania jest niejednoznaczny.

Odpowiedzi:


338

PID ostatniego wykonanego polecenia znajduje się w $!zmiennej powłoki:

my-app &
echo $!

1
Drukuje pid jak np. [1] 893. Chcę tylko numer.
user3153014

33
Należy zauważyć, że oznacza to programy uruchamiane w tle . Jeśli nie uruchomiono żadnych procesów w tle, parametr nie jest ustawiony.
ramrunner,

5
Inne godne rozwiązanie jest sugerowane w (komentarz do odpowiedzi na) Jak uzyskać pid dopiero rozpoczętego procesu : och, a „oneliner”: /bin/sh -c 'echo $$>/tmp/my.pid && exec program args' &- dysfunkcja 24 listopada 10 o 14:28
imz - Ivan Zakharyaschev

14
@ user3153014 Ciągi takie jak „[2] 2625” są drukowane przez powłokę po uruchomieniu zadania w tle. Nie ma to związku z produkcjąecho $!
Petr Gladkikh

Zwykle używam takiego kodu w skrypcie, gdy muszę czekać do zakończenia procesu. my-app & myVar=$! ; fg. fgponownie przenosi proces na pierwszy plan. Następnie mogę wydrukować echo $myVarpóźniej i jestem prawie pewien, że moja aplikacja już się zakończyła.
Vrata Błażek

66

Uzyskaj PID:

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

Zapisz PIDw zmiennej:

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

Zapisz wszystkie wystąpienia PIDw pliku tekstowym:

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

Zapisz dane wyjściowe, błędy i PIDoddzielne pliki:

#!/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
Pytanie nie dotyczyło przekierowania, więc twoja odpowiedź jest w większości taka sama, jak zaakceptowana, z tym wyjątkiem, że jeśli instancja my-appzakończy się, a może nawet gorzej, PID zostanie ponownie wykorzystany później, będziesz mieć złe informacje w pliku. Nie sądzę, aby ta odpowiedź naprawdę
dodawała

@EricRenouf post zaktualizowany!
Eduardo Cuomo

inna pochodna, która może być przydatna. Otrzymuje PID i jednocześnie traktuje go jako (głównie) proces pierwszego planu: sleep 4 | grep INVALID & export MY_PID=$!; fg; echo $MY_PID returned with $?`
mlathe 26.04.18

nie jest APP = main &sposób na złapanie PID?
MrMesees,

3

Spróbuj czegoś takiego

pidof my_app >> /tmp/my_app.pid

1
zewnętrzne polecenie i powolne, jeśli system może podać PID bezpośrednio, po co przeszukiwać wszystkie procesy, aby znaleźć właśnie to? a także, nie mogę być pewien, że otrzymasz poprawną wartość
papo

-4

Wypróbuj coś takiego:

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

Umieszczając pierwszą literę procesu między, [ ]upewnia się, że grepproces nie pojawi się na liście. W razie potrzeby możesz również dodać grep do swojej nazwy użytkownika.


9
W najlepszym razie my-appjest to bardzo delikatne i nie działa, jeśli jest wykonywane więcej niż jeden raz - davidshen84 szczególnie martwi się tym cas.
Mat

2
Jeśli nawet pójdziesz tą drogą, powinieneś użyć pgrepzamiast tego.
Willem,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.