Zakończ każdy proces w tle

10

Mam kilka Stoppedprocesów w tle.

kill $(jobs -p)i kill `jobs -p`nie mają wpływu

kill %1, kill %2itp. zakończono pomyślnie poszczególne procesy

Jak mogę zabić każdy proces w tle za pomocą jednego polecenia?

Ponadto, dlaczego pierwsze dwa polecenia nie działają dla mnie?

Używam Linux Mint 15, 64-bit

użytkownik49888
źródło

Odpowiedzi:

10

Kiedy biegną

Wygląda na to, że możesz to po prostu zrobić z killwyjściem jobs -p.

Przykład

$ sleep 1000 &
[1] 21952
$ sleep 1000 &
[2] 21956
$ sleep 1000 &
[3] 21960

Teraz mam 3 fałszywe zadania.

$ jobs
[1]   Running                 sleep 1000 &
[2]-  Running                 sleep 1000 &
[3]+  Running                 sleep 1000 &

Zabij ich wszystkich w ten sposób:

$ kill $(jobs -p)
[1]   Terminated              sleep 1000
[2]-  Terminated              sleep 1000
[3]+  Terminated              sleep 1000

Potwierdzając, że wszyscy zniknęli.

$ jobs
$

Kiedy zostaną zatrzymani

Jeśli masz zadania, które są zatrzymane, nie uruchomione, zrób to zamiast tego.

Przykład

$ kill $(jobs -p)

$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Stopped                 sleep 1000
[3]   Stopped                 sleep 1000

OK, żeby ich nie zabić, ale to dlatego, że sam proces zabicia nie może obsłużyć sygnału zabicia, jest zatrzymany. Więc zamiast tego powiedz systemowi operacyjnemu zabijanie. Po to -9jest a .

$ kill -9 $(jobs -p)
[1]+  Killed                  sleep 1000
[2]-  Killed                  sleep 1000
[3]   Killed                  sleep 1000

Tak lepiej

$ jobs
$ 

Gdy niektóre działają, a niektóre są zatrzymane

Jeśli masz mieszany zestaw procesów, w których niektóre są zatrzymywane, a niektóre są uruchomione, możesz zrobić killpierwszy, a następnie kill -9.

$ kill $(jobs -p); sleep <time>; \
    kill -18 $(jobs -p); sleep <time>; kill -9 $(jobs -p)

Nieco wydłużając czas, jeśli potrzebujesz więcej, aby procesy mogły się najpierw zatrzymać.

Sygnały

Ani HUP (-1), ani SIGTERM (-15) do zabicia się nie powiedzie. Ale dlaczego? To dlatego, że sygnały te są milsze w tym sensie, że każą aplikacji się zakończyć. Ale ponieważ aplikacja jest w stanie zatrzymania, nie może przetwarzać tych sygnałów. Jedynym oczywiście jest użycie SIGKILL (-9).

Możesz zobaczyć wszystkie sygnały, które killzapewnia kill -l.

$ kill -l | column -t
1)   SIGHUP       2)   SIGINT       3)   SIGQUIT      4)   SIGILL       5)   SIGTRAP
6)   SIGABRT      7)   SIGBUS       8)   SIGFPE       9)   SIGKILL      10)  SIGUSR1
11)  SIGSEGV      12)  SIGUSR2      13)  SIGPIPE      14)  SIGALRM      15)  SIGTERM
16)  SIGSTKFLT    17)  SIGCHLD      18)  SIGCONT      19)  SIGSTOP      20)  SIGTSTP
21)  SIGTTIN      22)  SIGTTOU      23)  SIGURG       24)  SIGXCPU      25)  SIGXFSZ
26)  SIGVTALRM    27)  SIGPROF      28)  SIGWINCH     29)  SIGIO        30)  SIGPWR
31)  SIGSYS       34)  SIGRTMIN     35)  SIGRTMIN+1   36)  SIGRTMIN+2   37)  SIGRTMIN+3
38)  SIGRTMIN+4   39)  SIGRTMIN+5   40)  SIGRTMIN+6   41)  SIGRTMIN+7   42)  SIGRTMIN+8
43)  SIGRTMIN+9   44)  SIGRTMIN+10  45)  SIGRTMIN+11  46)  SIGRTMIN+12  47)  SIGRTMIN+13
48)  SIGRTMIN+14  49)  SIGRTMIN+15  50)  SIGRTMAX-14  51)  SIGRTMAX-13  52)  SIGRTMAX-12
53)  SIGRTMAX-11  54)  SIGRTMAX-10  55)  SIGRTMAX-9   56)  SIGRTMAX-8   57)  SIGRTMAX-7
58)  SIGRTMAX-6   59)  SIGRTMAX-5   60)  SIGRTMAX-4   61)  SIGRTMAX-3   62)  SIGRTMAX-2
63)  SIGRTMAX-1   64)  SIGRTMAX

Jeśli chcesz dowiedzieć się jeszcze więcej na temat różnych sygnałów gorąco zachęcać do obejrzenia na stronie sygnały mężczyzna, man 7 signal.

slm
źródło
dlaczego mamy +symbol dla pierwszego procesu i -symbol dla drugiego procesu, a brak symbolu w trzecim?
Ramesh
Mam takie same wyniki jak ty. Jednak chcę terminatezamiast tego kill, ponieważ przeczytałem, że jest to bezpieczniejsze. Próbowałem kill -15 $(jobs -p), ale to nie przyniosło efektu. Domyślam się, że zatrzymane procesy można tylko zabić, ale potem ponownie kill %numberprzerywa (indywidualne) zatrzymane procesy.
user49888
@Ramesh The +i -to tylko ostatnie procesy, których dotknąłem, gdy tworzyłem przykłady. Te +środki, aby wszelkie polecenia, które wyraźnie nie zawierać %#będzie działać na tej komendzie. Dash ( -) jest drugim do ostatniego polecenia, którego dotknąłem.
slm
@ user49888 - kill -9 .. powinien był działać. jakie są procesy Czy są to procesy nieczynne czy osierocone?
slm
1
@ user49888 - tak, jeśli proces był w trakcie czegoś, nie ma możliwości wykonania żadnego czyszczenia przed zakończeniem.
slm
2

Możesz tego spróbować.

for x in `jobs -p`; do kill -9 $x; done

Jeśli jednak chcesz zakończyć proces, możesz wydać polecenie jako:

for x in `jobs -p`; do kill -15 $x; done

Na stronie polecenia WikiKill

Procesowi można wysłać sygnał SIGTERM na cztery sposoby (w tym przypadku ID procesu to „1234”):

kill 1234
kill -s TERM 1234
kill -TERM 1234
kill -15 1234

Do procesu można wysłać sygnał SIGKILL na trzy sposoby:

kill -s KILL 1234
kill -KILL 1234
kill -9 1234

Jak wyjaśniono w tej odpowiedzi, jest to różnica między zakończeniem a zabiciem .

Sygnał zakończenia, SIGTERM , jest sygnałem, który można przechwycić w programie. Często procesy, które mają działać w tle, wychwytują ten sygnał i rozpoczynają proces zamykania, co powoduje czyste wyjście. Sygnał zabicia, SIGKILL , nie może zostać przechwycony. Gdy zostanie wysłany do procesu, spowoduje to nagłe zakończenie tego programu.

Na przykład podczas zamykania lub ponownego uruchamiania komputera zwykle SIGTERM jest wysyłany do uruchomionych procesów, umożliwiając im zakończenie w czysty sposób, jeśli obsługują ten proces. Następnie, po kilku sekundach, SIGKILL jest wysyłany do procesów, które są nadal uruchomione, dzięki czemu zasoby w użyciu są uwalniane siłą (np. Pliki w użyciu) i sekwencja zamykania może być kontynuowana (np. Odmontowywanie systemów plików).

Ramesh
źródło
Robi to killkażdy proces w tle. Czy istnieje jednak jakikolwiek sposób terminate, skoro uważam, że jest to bezpieczniejsze?
user49888
Jeśli chcesz zakończyć, możesz użyć -15polecenia kill.
Ramesh
-15tutaj też nie będzie działać. Zobacz moje A.
slm
@Ramesh - ostatnie 2 akapity są nieprawidłowe. SIGTERM nie jest wysyłany (nie początkowo). Najpierw próbuje się zatrzymać procesy za pomocą tam skryptów stop / start usługi. Gdyby tak było, gdy do procesu wysłano 9, wówczas procesy zostały zatrzymane, jak w przykładzie PO, kill -9w moim przykładzie nie zadziałałoby.
slm
1

Ok, bawiąc się z tym, widzę, że kiedy zabijesz zadanie, które jest zatrzymane (gdzie wykonywanie zostało wstrzymane, ale nie zostało zakończone), to nie skończy się, dopóki nie zostanie przeniesione na pierwszy plan. Programy są zwykle zatrzymywane przez naciśnięcie Ctrl- Zna terminalu. Większość terminali wysyła SIGSTOPw tym przypadku, ale oczywiście są też inne sposoby wysyłania, takie jak za pomocą kill -STOPlub kill -19.

To normalne zachowanie, że program nie kończy się od razu, ponieważ program musi być uruchomiony, aby przetworzyć domyślny SIGTERMsygnał wysłany przez kill. Co więcej, czasami po bashwysłaniu SIGTERMdo procesu w tle, jakoś kończy się zatrzymanie (chociaż SIGTERMnadal jest w toku).

Najbezpieczniejszym sposobem na zakończenie wszystkich zadań ( bez uciekania się do nich kill -9) jest wysłanie SIGTERMnormalnego kill, a następnie wysłanie SIGCONTdo pozostałych zadań, np .:

kill $(jobs -p)
kill -18 $(jobs -p)

SIGCONT( 18To numer sygnału) przyniesie żadnych zatrzymane pracy na planie tak, że mogą one przetwarzać SIGTERM, ponieważ zwykle.

Jeśli wszystkie programy nie zakończą się tym, istnieje kilka innych sygnałów, które można wypróbować, które normalnie zakończą proces, zanim uciekniesz się do niego kill -9. Pierwszy polecam, SIGHUPponieważ wiele programów, które zwykle blokują inne sygnały zakończenia, odpowiada SIGHUP. Jest to zwykle wysyłane, gdy terminal kontrolny zostanie zamknięty, w szczególności jest wysyłane, gdy kończy się sshsesja tty. Wiele programów interaktywnych, takich jak powłoki, nie reaguje na inne sygnały zakończenia, ale reaguje na to, ponieważ byłoby problem z ich kontynuowaniem po sshzakończeniu sesji (lub po zamknięciu dowolnego kontrolującego terminala). Aby tego spróbować, możesz to zrobić

kill -1 $(jobs -p)
kill -18 $(jobs -p)

Znowu oczywiście musisz upewnić się, że program nie został zatrzymany, aby mógł przetworzyć sygnał. Inne sygnały zakończenia, które możesz wypróbować, to SIGINT( kill -2) i SIGQUIT( kill -3). Ale oczywiście korzyści wynikające z wypróbowania pełnego zakresu zmniejszają się i mogą prowadzić do nieuniknionego SIGKILL(aka kill -9).

Graeme
źródło
Jeśli to zrobisz man signal, możesz zdobyć materiał referencyjny, aby to zrobić .
slm
Jest to bardziej miękka forma tego, co sugeruje mój A. Są przypadki, w których natknąłem się w przeszłości, gdzie to nadal nie wyczyści w pełni rzeczy, więc jeśli robisz to ze skryptu, kill -9 ..metoda będzie działać w większości przypadków. Czasami spowoduje to, że procesy będą się zawieszać, więc przez dłuższy czas zawiedzie. To kompromis, który musisz podjąć. Lepiej mieć ciężką rękę i zabijać wszystko, ryzykując dane / czyszczenie w porównaniu z bardziej miękkim czyszczeniem, ale musisz robić więcej analiz, gdy twoje zabójstwa stają się coraz bardziej surowe.
slm
@slm, powinieneś unikać, kill -9gdy tylko jest to możliwe, ponieważ po prostu wyciąga wtyczkę, nie dając programowi szansy na prawidłowe wyczyszczenie. Zaktualizuję z kilkoma alternatywami.
Graeme
Jak powiedziałem, twój smak jest łagodniejszy niż sugerowałem, sprowadza się do tego, co próbujesz zrobić, a nie do zaakceptowania z perspektywy ryzyka. Użyłem twojej metody, podobnie jak mojej. Oboje mają poprawne IMO. Również a kill ..; sleep <time>; kill -18 ..; spać <czas>; zabij -9 ... . Basically working up to the -9`.
slm
@slm, kill -18jest zdecydowanie czymś, z czego należy korzystać, ponieważ często są zatrzymywane zadania (a w niektórych przypadkach wydaje się, że w bashjakiś sposób przestają one uruchamiać zadania przed wysłaniem SIGTERM). Jak wspomniano powyżej, SIGHUPwarto również spróbować, ponieważ wiele programów, które nie reagują na inne, odpowie na to (wypróbuj to z powłoką). Poza tym tak, nie jest to tak opłacalne, ponieważ SIGKILLprawdopodobnie jest nieuniknione.
Graeme
0

Spowoduje to zakończenie wszystkich zadań w bieżącej powłoce jeden po drugim:

while kill %; do :; done

Objaśnienie: %odnosi się do ostatniego zadania na liście, więc będzie się zapętlać, dopóki killnie zwróci wartości niezerowej, co oznaczałoby, że nie ma już więcej zadań do zakończenia.

Innym podejściem może być najpierw wysłanie SIGTERM, a następnie SIGCONTkontynuowanie pracy i pierwszą rzeczą, którą zrobią, będzie otrzymanie Twojej SIGTERM.

/bin/kill $(jobs -p) && /bin/kill -CONT $(jobs -p)

(z jakiegoś powodu wbudowane killjest dziwne, więc użyłem tutaj zewnętrznego).

dnt
źródło