linux: zabij zadanie w tle

194

Jak zabić ostatnie odrodzone zadanie w tle w systemie Linux?

Przykład:

doSomething
doAnotherThing
doB &
doC
doD
#kill doB
????
Lecieć jak po sznurku
źródło
18
Jak może to nie być związane z programowaniem? Programowanie Bash nie programuje?
flybywire
6
Jest to w obszarze nakładania się SO i SU, ale myślę, że lepiej pasuje tutaj w SO. Moje kryteria takiego myślenia są takie, że jeśli @flybywire robi to w skrypcie, programuje. Gdyby tylko chciał to zrobić z wiersza poleceń, powiedziałbym, że należy do SU.
Bill the Lizard
10
Programuje się również skrypty powłoki.
cletus

Odpowiedzi:

234

W bash dostępna jest specjalna zmienna:

kill $!

$! rozwija się do PID ostatniego procesu wykonanego w tle.

falstro
źródło
68
@ polm23; nie, ^Znie wykonuje zadań w tle, zatrzymuje je. Następnie bgwykonuje rzeczywiste „tło” (wznawia wykonywanie w tle), a następnie $!działa zgodnie z oczekiwaniami.
falstro
Zakładając, że ????stoi jeden lub więcej poleceń do wykonania po zabiciu, jeśli którekolwiek z tych poleceń zależy od pracy wykonanej przez proces w tle, pamiętaj o wszelkich zadaniach czyszczenia lub wykończenia, które proces w tle może wykonać w module obsługi sygnału po odbieranie (pułapkowego) sygnału. Najlepiej dodać wait(po którym może być a, synca nawet a sleep <n>) tuż przed pierwszą z takich komend „zależnych”.
ack
2
Do zakończenia: ponieważ pojedynczy% odnosi się również do bieżącego zadania, możesz zabić zatrzymane zadanie (^ z) za pomocą „kill%”. Używam tego prawie zawsze po ^ z.
t3o
Działa to tylko wtedy, gdy masz włączoną kontrolę zadań, która jest domyślnie włączona tylko w interaktywnych powłokach (chociaż skoro mówisz o użyciu ctrl-z, myślę, że masz również na myśli użycie interaktywnej powłoki) - ale tak było przedstawione w innych odpowiedziach tutaj, nie jestem pewien, dlaczego to jest „dla kompletności” :)
falstro
289

Możesz zabić według numeru zadania. Po umieszczeniu zadania w tle zobaczysz coś takiego:

$ ./script &
[1] 35341

Jest [1]to numer zadania i można się do niego odwoływać w następujący sposób:

$ kill %1
$ kill %%  # Most recent background job

Aby wyświetlić listę numerów zadań, użyj jobspolecenia. Więcej od man bash:

Istnieje wiele sposobów odwoływania się do zadania w powłoce. Postać %wprowadza nazwę zadania. Numer zadania nmoże być określany jako %n. Zadanie może być również przywołane przy użyciu prefiksu nazwy użytej do jego uruchomienia lub przy użyciu podłańcucha, który pojawia się w jego wierszu poleceń. Na przykład %ceodnosi się do zatrzymanego cezadania. Jeśli prefiks pasuje do więcej niż jednego zadania, bash zgłasza błąd. %?ceNatomiast użycie odnosi się do każdego zadania zawierającego ciąg znaków cew wierszu poleceń. Jeśli podłańcuch pasuje do więcej niż jednego zadania, bash zgłasza błąd. Symbole %%i%+odnoszą się do pojęcia powłoki bieżącego zadania, które jest ostatnim zadaniem zatrzymanym, gdy było na pierwszym planie lub rozpoczęło się w tle. Do poprzedniego zadania można się odwołać za pomocą %-. W danych wyjściowych dotyczących zadań (np. Danych wyjściowych polecenia zadań) bieżące zadanie jest zawsze oznaczane za pomocą a +, a poprzednie zadanie za pomocą -. Pojedyncza %(bez towarzyszącej specyfikacji pracy) odnosi się również do bieżącej pracy.

John Kugelman
źródło
Dla przypomnienia, myślę, że działa to tylko wtedy, gdy kontrola zadań jest włączona. Chociaż myślę, że można go włączyć w skryptach ( set -m), jest on przeznaczony do użytku interaktywnego. Zobacz stackoverflow.com/questions/690266/... także
falstro
9
Bardzo przydatne symbole, te %1i %%- zwłaszcza. Niektóre rzeczy nie umierają na Ctrl-C, więc musisz je Ctrl-Z, a potem kill -9 %%. Jednym z przykładów, w którym uznałem to za przydatne, jest: while true; do mplayer <some unstable online radio>; date >> restarts.log; done- Ctrl-C poprowadzi cię do następnej iteracji w pętli. Zanim musiałem to zrobić, psa może jobs -l, a następnie ponownie wpisać PID, co jest uciążliwe.
Tomasz Gandor
Czy istnieje jeden dla wszystkich prac?
CMCDragonkai
3
@TomaszGandor Dlatego warto wymienić while truez while sleep 1. To da ci krótkie opóźnienie przed ponownym uruchomieniem, jeśli możesz z tym żyć, a jeśli naciśniesz ctrl-c dwa razy, drugi przerwie sen, kończąc go niezerowym wyjściem i wyjściem z pętli.
falstro
45

Poniższe polecenie zawiera listę wszystkich procesów w tle w sesji wraz z pid. Następnie możesz go użyć do zabicia procesu.

jobs -l

Przykładowe użycie:

$ sleep 300 &
$ jobs -l
[1]+ 31139 Running                 sleep 300 &
$ kill 31139
Dave Vogt
źródło
25

To powinno zabić wszystkie procesy w tle:

jobs -p | xargs kill -9
Prabhu Are
źródło
1
Tego właśnie użyłem wcześniej, ale kill -9 %%mniej pisze :)
Tomasz Gandor
4
@TomaszGandor To zabije tylko bieżącą pracę, tj. Ostatnią pracę zatrzymaną na pierwszym planie lub uruchomioną w tle. Polecenie w odpowiedzi zabije WSZYSTKIE zadania.
bitek
4
nie zabijaj -9
lesmana
2
skill doB

skill to wersja polecenia kill, która pozwala wybrać jeden lub wiele procesów na podstawie podanych kryteriów.

gte525u
źródło
0

Potrzebujesz jego pid ... użyj „ps -A”, aby go znaleźć.

Jldupont
źródło
0

jest to odpowiedź nie na temat, ale dla zainteresowanych może być cenna.

Jak w odpowiedzi @Johna Kugelmana,% jest związany ze specyfikacją zadania. jak skutecznie to znaleźć? użyj komendy less's i wzorca , wygląda na to, że mężczyzna używa mniej pagera (nie jestem tego pewien), w man bash wpisz &%, a następnie wpisz Enter pokaże tylko wiersze zawierające '%', aby ponownie wyświetlić wszystko, wpisz &. następnie Enter.

qeatzy
źródło
-3

Wystarczy użyć polecenia killall:

killall nazwa zadania

Aby uzyskać więcej informacji i bardziej zaawansowane opcje, wpisz „man killall”.

zakk
źródło
4
Myślę, że killall jest nieco agresywny, kiedy faktycznie masz łatwy dostęp do PID. I niebezpieczne, szczególnie jeśli jesteś rootem
Dave Vogt,
3
Niezbyt pomocny, jeśli musiałeś killall pythonlub killall javamając coś pożytecznego w innym miejscu systemu.
Tomasz Gandor