2014-12-29 19 views
16

Próbuję złapać sygnał SIGUSR1 w skrypcie bash, który jest snem za pomocą polecenia sleep:przerwania snu w bash z pułapki sygnału

#!/bin/bash 

trap 'echo "Caught SIGUSR1"' SIGUSR1 

echo "Sleeping. Pid=$$" 
while : 
do 
    sleep 10 
    echo "Sleep over" 
done 

sygnał prac pułapkę, ale wiadomość jest echem jest nie wyświetla się, dopóki nie zakończy się sleep 10.
Wygląda na to, że obsługa sygnału bash czeka aż bieżące polecenie zostanie zakończone przed przetworzeniem sygnału.

Czy istnieje sposób, aby przerwać uruchomione polecenie sleep, gdy tylko otrzyma sygnał, w ten sam sposób, w jaki program C przerwałby funkcję libc sleep()?

Odpowiedz

18
#!/bin/bash 

trap 'echo "Caught SIGUSR1"' SIGUSR1 

echo "Sleeping. Pid=$$" 
while : 
do 
    sleep 10 & 
    wait $! 
    echo "Sleep over" 
done 
+8

Niektóre [istotne info] (http://mywiki.wooledge.org/SignalTrap#When_is_the_signal_handled.3F) – iruvar

+1

Wymień 10 od nieskończoności, takich jak „uśpienia nieskończoności &” – gregoiregentil

+0

@iruvar link jest warta swojej wagi w złocie. nie jest w stanie przerwać snu z innego procesu * bardzo, bardzo, bardzo intuicyjnie *. –

2

Uwaga że

sleep infinity & 
wait 

kładzie spać w tle, i zatrzymuje poczekać z sygnałem. To pozostawia nieskończony sen za każdym sygnałem!

Wymień spać i czekać z

read 

i będzie w porządku.

+0

Nie wydaje mi się, żeby zawiesił się proces w tle, przynajmniej nie na MacOS 10.12. – frnhr

6

tylko punkt o wait po sleep bo właśnie popełnił ten błąd w moim skryptu:

Należy użyć wait $! zamiast wait jeśli wewnątrz skryptu, to już uruchomiona inna procesy w tle

na przykład wait wewnątrz kolejnego fragmentu kodu będzie czekać dla o zakańczania f zarówno process_1 i sleep 10:

process_1 & 
    ... 
sleep 10 & 
wait 

Jeśli używasz zamiast wait, wait $! skrypt będzie czekać tylko dla sleep 10, ponieważ $! oznacza PID ostatniego działających w tle procesów.

+0

Wielkie dzięki! Zmieniłem moją odpowiedź zgodnie z sugestią Ciebie. –

Powiązane problemy