[Edycja: Wygląda podobnie do niektórych innych pytań dotyczących sposobu zabicia wszystkich spawnowanych procesów - wszystkie odpowiedzi wydają się używać pkill. Więc rdzeniem mojego pytania może być: Czy istnieje sposób na propagowanie Ctrl-C / Z we wszystkich procesach spawnowanych przez skrypt?]
Podczas wywoływania SoX rec
za pomocą timeout
polecenia z coreutils (omówione tutaj ), wydaje się, że nie ma sposobu na zabicie go za pomocą klawisza po wywołaniu go ze skryptu Bash.
Przykłady:
timeout 10 rec test.wav
... można zabić za pomocą Ctrl+ Club Ctrl+ Zz bash, ale nie wtedy, gdy zostanie wywołany z poziomu skryptu.
timeout 10 ping nowhere
... można zabić za pomocą Ctrl+ Club Ctrl+ Zz bash i Ctrl+, Zgdy jest uruchamiany ze skryptu.
Mogę znaleźć identyfikator procesu i zabić go w ten sposób, ale dlaczego nie mogę użyć standardowego naciśnięcia klawisza break? Czy jest jakiś sposób na ustrukturyzowanie mojego skryptu, aby mógł?
źródło
bg
zfg
poleceniami. W każdym razie, czy jest jakaś różnica między twoim 1. a 3d przykładem?timeout
w swoim systemie, ale zabijaniesleep
działa bez względu na to, czy jest wpisywane bezpośrednio w wierszu polecenia, pozyskiwane, wykonywane lub przekazywane jawnie przez tłumaczaOdpowiedzi:
Klawisze sygnałowe, takie jak Ctrl+, Cwysyłają sygnał do wszystkich procesów w grupie procesów pierwszego planu .
W typowym przypadku grupa procesów jest potokiem. Na przykład
head <somefile | sort
wewnątrz proces działającyhead
i proces działającysort
należą do tej samej grupy procesów, co powłoka, więc wszystkie odbierają sygnał. Po uruchomieniu zadania w tle (somecommand &
) zadanie to znajduje się we własnej grupie procesów, więc naciśnięcie Ctrl+ Cnie ma na niego wpływu.timeout
Program umieszcza się we własnej grupie procesowej. Z kodu źródłowego:Gdy nastąpi przerwa,
timeout
przechodzi przez prosty cel polegający na zabiciu grupy procesów, której jest członkiem. Ponieważ znalazł się w osobnej grupie procesów, jego proces nadrzędny nie będzie w tej grupie. Użycie tutaj grupy procesów zapewnia, że jeśli aplikacja potomna rozwidli się na kilka procesów, wszystkie jej procesy otrzymają sygnał.Kiedy uruchomisz
timeout
bezpośrednio w linii poleceń i naciśniesz Ctrl+ C, wynikowy SIGINT zostanie odebrany zarówno przeztimeout
proces potomny, jak i przez proces potomny, ale nie przez interaktywną powłokę, która jesttimeout
procesem macierzystym. Kiedytimeout
jest wywoływany ze skryptu, tylko powłoka, która go uruchamia, odbiera sygnał:timeout
nie odbiera go, ponieważ znajduje się w innej grupie procesów.Możesz ustawić moduł obsługi sygnału w skrypcie powłoki z
trap
wbudowanym. Niestety nie jest to takie proste. Rozważ to:Jeśli naciśniesz Ctrl+ Cpo 2 sekundach, nadal czeka to pełne 5 sekund, a następnie wydrukujesz komunikat „Przerwany”. Jest tak, ponieważ powłoka powstrzymuje się od uruchamiania kodu pułapki, gdy aktywne jest zadanie pierwszoplanowe.
Aby temu zaradzić, uruchom zadanie w tle. W module obsługi sygnałów wywołaj,
kill
aby przekazać sygnał dotimeout
grupy procesów.źródło
Opierając się na doskonałej odpowiedzi udzielonej przez Gillesa. Polecenie timeout ma opcję pierwszoplanową, jeśli zostanie użyte, CTRL + C zamknie polecenie timeout.
źródło
timeout
z GNU coreutils.Zasadniczo Ctrl+ Cwysyła
SIGINT
sygnał, podczas gdy Ctrl+ Z wysyłaSIGTSTP
sygnał.SIGTSTP
po prostu zatrzymuje proces iSIGCONT
będzie go kontynuować.Działa to na pierwszym planie, który został rozwidlony w wierszu polecenia.
Jeśli twój proces jest procesem w tle, będziesz musiał wysłać ten sygnał do procesów w inny sposób.
kill
zrobi to. Teoretycznie operator „-” tego zabicia powinien również sygnalizować procesy potomne, ale rzadko działa to zgodnie z oczekiwaniami.Do dalszego czytania: Sygnały uniksowe
źródło
Poprawa odpowiedzi @Gilles poprzez zastosowanie podejścia „znajdź i zamień” dla istniejących skryptów:
INT
obsługi:timeout
polecenia namy_timeout
funkcję w skrypcie.Przykład
Oto przykładowy skrypt:
źródło