2011-07-18 27 views
6

Potrzebuję podjąć pewne działanie w oparciu o wartość zwracaną procesu w tle, tj. Jeśli kończy się w pierwszej kolejności.Wartość zwracana procesu w tle

W szczególności: w idealnej operacji serwer, który uruchamiam jako proces w tle, będzie działał wiecznie. W takich przypadkach zachowanie go w tle ma sens, ponieważ chcę, aby mój skrypt powłoki robił inne rzeczy po spawnowaniu serwera. Ale jeśli serwer zakończy się nieprawidłowo, chcę użyć wartości zwracanej przez wyjście z serwera, aby zdecydować, czy mam zabić główny skrypt, czy nie. Jeśli nie jest to możliwe, przynajmniej chcę przerwać główny skrypt, zamiast uruchamiać go z uszkodzonym serwerem.

Szukam czegoś w postaci asynchronicznego wywołania zwrotnego dla skryptów powłoki. Jednym z rozwiązań jest odrodzenie procesu monitorowania, który okresowo sprawdza, czy serwer nie powiódł się, czy nie. Najlepiej byłoby zrobić to bez tego w samym głównym skrypcie powłoki.

Odpowiedz

-2

Można zagnieździć proces w tle wewnątrz skryptu. Na przykład, jeśli proces chcesz wysłać do tła jest nazywany foo:

#!/bin/sh 

foo 

if [ $? ] 
then 
    # do something here if process failed 
fi 

Następnie wystarczy uruchomić powyższy skrypt w tle zamiast foo. możesz go zabić, jeśli chcesz go wyłączyć, ale w przeciwnym razie nie zakończy się tak długo, jak długo trwa foo, a jeśli foo umrze, możesz zrobić, co chcesz, na podstawie jego kodu błędu.

2

Można użyć pułapek powłoki, aby wywołać funkcję, gdy dziecko wychodzi, przechwytując SIGCHLD. Jeśli działa tylko jeden proces działający w tle, możesz go uzyskać w programie obsługi sigchld i uzyskać tam status. Jeśli działa wiele dzieci w tle, staje się nieco bardziej skomplikowana; tutaj jest przykład kodu (testowany tylko z bash):

set -m # enable job control 
prtchld() { 
    joblist=$(jobs -l | tr "\n" "^") 
    while read -a jl -d "^"; do 
    if [ ${jl[2]} == "Exit" ] ; then 
     job=${jl[1]} 
     status=${jl[3]} 
     task=${jl[*]:4} 
     break 
    fi 
    done <<< $joblist 
    wait $job 
    echo job $task exited: $status 
} 
trap prtchld SIGCHLD 

(sleep 5 ; exit 5) & 
(sleep 1 ; exit 7) & 

echo stuff is running 

wait 
0

Najpierw podoba mi się ten pierwszy, zakładam, że "zrób coś tutaj, jeśli proces się nie powiedzie". Mogę zabić skrypt, który nazwał ten skrypt otoki dla foo, używając jego nazwy.

Myślę, że pierwsze rozwiązanie działa dobrze dla wielu dzieci. W każdym razie musiałem to zrobić szybko, więc użyłem hacka, który działa dla mojej aplikacji:

Rozpoczęcie procesu w tle jak zwykle w głównym skrypcie, a następnie użyj $! aby otrzymać pid (od $! zwraca ostatni bg pid), przespać 2 sekundy i zrobić ps -e | grep pid, aby sprawdzić, czy proces nadal trwa w oparciu o zwracaną wartość (ps -e | grep pid). Działa to dobrze, ponieważ jeśli mój proces w tle zostanie przerwany, robi to natychmiast (ponieważ adres jest w użyciu).