2012-02-13 15 views
29

muszę skrypt bash, który wykonuje następujące czynności:Jak mogę uzyskać zarówno identyfikator procesu, jak i kod wyjścia ze skryptu bash?

  • Uruchamia proces tła z całej produkcji skierowanej do pliku
  • Zapisuje kod zakończenia procesu do pliku
  • Zwraca PID procesu (od razu , a nie kiedy proces wychodzi).
  • Skrypt musi wyjść

mogę PID ale nie kod wyjścia:

$ executable >>$log 2>&1 & 
pid=`jobs -p` 

Lub mogę zdobyć kod wyjścia, ale nie PID:

$ executable >>$log; 
# blocked on previous line until process exits 
echo $0 >>$log; 

Jak mogę wykonać wszystkie te czynności w tym samym czasie?

Odpowiedz

53

PID jest w $!, nie trzeba uruchamiać jobs. I zwracany jest zwracany przez wait:

$executable >> $log 2>&1 & 
pid=$! 
wait $! 
echo $? # return status of $executable 

EDIT 1

Jeśli Rozumiem dodatkowy wymóg jak podano w komentarzu, a chcesz skrypt natychmiast (powrót bez czekania na komendę do końca), wówczas początkowy skrypt nie będzie mógł zapisać stanu wyjścia polecenia. Ale wystarczy, że pośrednik napisze status wyjścia, gdy dziecko skończy. Coś jak:

sh -c "$executable"' & echo pid=$! > pidfile; wait $!; echo $? > exit-status' & 

powinien działać.

EDIT 2

Jak zauważył w komentarzach, że roztwór ma sytuacji wyścigu: główny skrypt kończy przed pidfile jest napisane. PO rozwiązuje to, wykonując pętlę snu wyborczego, co jest obrzydliwością i obawiam się, że będę miał problemy ze snem w nocy, wiedząc, że mogłem zmotywować taką parodię. IMO, właściwym rozwiązaniem jest poczekać, aż dziecko skończy. Ponieważ jest to nie do przyjęcia, o to rozwiązanie, które bloki na odczytu aż plik pid istnieje zamiast robić sen pętli:

{ sh -c "$executable > $log 2>&1 &"' 
echo $! > pidfile 
echo # Alert parent that the pidfile has been written 
wait $! 
echo $? > exit-status 
' & } | read 
+0

dzięki. To całkiem blisko. Obawiam się, że odstąpiłem od jednego innego wymogu. Skrypt basha musi się zakończyć. Jeśli uruchomię "wait $ pid; echo $? >> $ log" w pomocniczym skrypcie pomocniczym, otrzymam błąd "nie jest dzieckiem". –

+2

Jeśli chcesz, aby skrypt zakończył działanie przed zakończeniem podrzędnego, nie można zapisać kodu zakończenia dziecka bez wywoływania jakiejś anomalii temporalnej. –

+0

Zawiń całe 'sh -c" ($ executable "'... exit-status)' & 'w nawiasach pod-powłokę. To pozwala podpowierzchniom zabrać się za życie, podczas gdy rodzic radzi sobie z tym, co musi zrobić. Możesz dodać kolejne '&' po ')'. –

Powiązane problemy