Zabij wszystkie zadania w tle


63

Czy istnieje bardziej zwarta forma zabijania zadań w tle niż:

for i in {1..5}; do kill %$i; done

Ponadto {1..5} ma oczywiście zakodowaną na stałe magiczną liczbę, jak mogę ustawić ją jako „N”, przy czym N jest właściwą liczbą, bez robienia:

$(jobs | wc -l)

Używam \ j na PS1, aby uzyskać # zarządzanych zadań, czy to równoważne?


3
kill $(jobs -p)wydaje się łatwiejsze.
jw013

W miarę możliwości wolałbym zabijać zlecenia indywidualnie. (
Być

for pid in $(jobs -p); do kill $pid; done?
jw013,

3
@ jw013 Jest to nie tylko łatwiejsze, ale w rzeczywistości poprawne (proszę opublikować je jako odpowiedź), w przeciwieństwie do rozwiązania polegającego na zliczaniu wierszy wyniku, jobsktóre działa tylko wtedy, gdy zadania są kolejno numerowane. Aha, i „zabijaj zadania indywidualnie” nie ma znaczenia: przekazywanie wielu PID do killpolecenia robi dokładnie to samo, co przekazywanie ich osobno.
Gilles,

Wprowadzałem polecenie niepoprawnie, zabiłem słowa $ (jobs -p) i dla mnie też wygląda to bardzo poprawnie. Gotowy do przyjęcia.
Robottinosino,

Odpowiedzi:


102

Aby tylko killwszystkie zadania w tle zarządzane przez bash, wykonaj

kill $(jobs -p)

Należy zauważyć, że ponieważ oba jobsi killsą wbudowane bash, nie należy się żadne błędy na liście argumentów zbyt długo typu.


2
Również dla potomności to, co uważa bahamat, jest sposobem na to, by zshdyskwalifikować ich jako jakiekolwiek autorytety w tej dziedzinie.
peth

Czuję, że powinienem to wiedzieć, ale jak działa tutaj „$”?
fersarr

1
@fersarr Proszę bardzo
jw013

@bahamat To nie działa, ponieważ PID może znajdować się w polu 2 lub 3 w zależności od tego, czy zadanie ma wartość% + czy% - czy nie. To, co działa kill %${(k)^jobdirs}, jest rzeczywiście dłuższe; jeśli musisz podać PID, możesz użyć jeszcze dłuższego ${${jobstates#*:*:}%%=*}.
Gilles

W CentOS moja zachęta czeka na więcej informacji>
Janac Meena

15

Użyj xargszamiast $(jobs -p)podkomendy, ponieważ jeśli jobs -pjest pusta, polecenie zabicia zakończy się niepowodzeniem.

jobs -p | xargs kill

1
Ma to ten sam dokładny efekt, wypisuje pomoc i wychodzi z kodem 123
cat

1
Polecenie działa dobrze w OSX, ale nie działa w Debianie
brunocascio,

Działa to świetnie na CentOS 6
Janac Meena

jobs -p | xargs -rn10 killzrobi się lepiej, jeśli jobs -pnie zwróci żadnych PID. Zauważ, że -ropcja to rozszerzenie GNU.
NarūnasK

Jak wspomniano powyżej, -rjest to krótki format --no-run-if-emptyrozszerzenia GNU, xargsktóry nakazuje mu nie uruchamiać polecenia, jeśli stdin nie ma danych.
Anthony Geoghegan

3

Wolę sprawdzić, czy istnieją jakieś zadania przed ich zabiciem - w ten sposób skrypt nie zawiedzie, jeśli nic nie działa.

Jest także krótszy do pisania. Rzuć to w .bash_profile:

function killjobs () {
    JOBS="$(jobs -p)";
    if [ -n "${JOBS}" ]; then;
        kill -KILL ${JOBS};
    fi
}

Następnie uruchomić:

killjobs

Aby zabić uruchomione zadania.


1

Mam kilka złożonych komend w tle, które chcę zakończyć z wdziękiem, wysyłając SIGINT do każdego procesu na macOS. Żadne z pozostałych rozwiązań nie działało poprawnie, więc wpadłem na to:

jobs -p | xargs -n1 pkill -SIGINT -g

jobs -p wyświetla procesy w tle uruchomione przez bieżącą powłokę.

xargs -n1 wykonuje pkill raz dla każdego zadania.

pkill -SIGINT -g wysyła SIGINT (tak samo jak ctrl + c) do wszystkich procesów w grupie procesów.


1

Myślę, że w zależności od tego, co jobs -pdaje wynik , rozwiązanie może być nieco inne. W moim przypadku

$ jobs -p
[1]  - 96029 running    some job
[2]  + 96111 running    some other job

Dlatego wykonanie następujących czynności nie jest dobre.

$ jobs -p | xargs kill
kill: illegal process id: [1]

Z drugiej strony, bieganie kill $(jobs -p)działa, ale pociąga za sobą wiele komunikatów o błędach, ponieważ przekazywane killsą również ciągi inne niż PID .

Dlatego moim rozwiązaniem jest grepnajpierw PID, a następnie użyć xargsw następujący sposób:

$ jobs -p | grep -o -E '\s\d+\s' | xargs kill

1
Jakiej powłoki używasz? Co echo $0pokazuje Co help jobspokazuje Przedstawione dane wyjściowe nie są zgodne z POSIX ; każda implementacja jobspowinna mieć -popcję z zamierzonym zachowaniem.
Wildcard

1
Dzięki za zwrócenie na to uwagi. Używam zsh i to jest przyczyną dziwnych wyników. Przełączyłem się na bash i jobs -pwyprowadziłem tylko PID. Właśnie dowiedziałem się, że zsh nie jest całkowicie zgodny z POSIX.
Fanchen Bao

0

Wygląda na jobs -p | xargs killto, że spełnia swoje zadanie, jednak generuje niechciane dane wyjściowe do zabicia. Tutaj grupuję dane wyjściowe jobs -pwedług / nie posiadających znaku + lub -

function killjobs() {
    JOBS=$(jobs -p)
    echo $JOBS | grep -v "+\|-"| awk '{print $2}' | xargs kill -9
    echo $JOBS | grep "+\|-"| awk '{print $3}' | xargs kill -9
}

A później możesz po prostu zadzwonić killjobs

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.