Możesz użyć sh -c
i, exec
aby uzyskać PID polecenia nawet przed jego uruchomieniem.
Aby rozpocząć myCommand
, aby wydrukować jego PID, zanim zacznie działać, możesz użyć:
sh -c 'echo $$; exec myCommand'
Jak to działa:
To uruchamia nową powłokę, drukuje PID tej powłoki, a następnie używa exec
wbudowanego do zastąpienia powłoki poleceniem, upewniając się, że ma ten sam PID. Kiedy twoja powłoka uruchamia polecenie z exec
wbudowanym narzędziem, to faktycznie staje się tym poleceniem , a nie bardziej powszechnym zachowaniem polegającym na tworzeniu nowej kopii, która ma swój własny PID, a następnie staje się poleceniem.
Uważam, że jest to o wiele prostsze niż alternatywy obejmujące asynchroniczne wykonywanie (z &
), kontrolę zadań lub wyszukiwanie za pomocą ps
. Te podejścia są w porządku, ale chyba że masz konkretny powód, aby z nich korzystać - na przykład być może polecenie już działa, w takim przypadku szukanie PID lub sterowanie zadaniami miałoby sens - sugeruję rozważenie tego w pierwszej kolejności. (I na pewno nie rozważyłbym napisania złożonego skryptu lub innego programu, aby to osiągnąć).
Ta odpowiedź zawiera przykład tej techniki.
Części tego polecenia można czasami pominąć, ale nie zwykle.
Nawet jeśli używana powłoka jest w stylu Bourne'a, a zatem obsługuje exec
wbudowaną semantykę, ogólnie nie powinieneś próbować unikać sh -c
(lub równoważnego) tworzenia nowego, osobnego procesu powłoki w tym celu, ponieważ:
- Gdy powłoka się stanie
myCommand
, nie będzie ona czekała na uruchomienie kolejnych poleceń. sh -c 'echo $$; exec myCommand; foo
nie będzie mógł uruchomić się foo
po zamianie na myCommand
. O ile nie piszesz skryptu, który uruchamia to jako ostatnie polecenie, nie możesz po prostu użyć echo $$; exec myCommand
w powłoce, w której uruchamiasz inne polecenia.
- Nie można do tego użyć podpowłoki .
(echo $$; exec myCommand)
może być ładniejszy niż składniowo sh -c 'echo $$; exec myCommand'
, ale po uruchomieniu $$
wewnątrz (
)
, daje PID powłoki macierzystej, a nie samej podpowłoce. Ale to PID podpowłoki będzie PID nowego polecenia. Niektóre powłoki zapewniają własne nieprzenośne mechanizmy wyszukiwania PID podpowłoki, których można użyć do tego celu. W szczególności, w Bash 4 , (echo $BASHPID; exec myCommand)
działa.
Na koniec zauważ, że niektóre powłoki wykonają optymalizację , uruchamiając polecenie tak, jakby do exec
(tj. Najpierw rezygnują z rozwidlenia), gdy wiadomo, że powłoka nie będzie musiała nic robić później. Niektóre powłoki próbują to zrobić za każdym razem, gdy jest to ostatnie polecenie do uruchomienia, podczas gdy inne zrobią to tylko wtedy, gdy nie będzie żadnych innych poleceń przed lub po poleceniu, a inne w ogóle tego nie zrobią. Efekt jest taki, że jeśli zapomnisz napisać exec
i po prostu użyć, sh -c 'echo $$; myCommand'
to czasami da ci odpowiedni PID w niektórych systemach z niektórymi powłokami. Odradzam poleganie na takim zachowaniu , a zamiast tego zawsze uwzględnianie, exec
kiedy tego potrzebujesz.