Znajdź i zabij proces w jednej linii za pomocą bash i regex


647

Często muszę zabić proces podczas programowania.

Teraz to robię:

[~]$ ps aux | grep 'python csp_build.py'
user    5124  1.0  0.3 214588 13852 pts/4    Sl+  11:19   0:00 python csp_build.py
user    5373  0.0  0.0   8096   960 pts/6    S+   11:20   0:00 grep python csp_build.py
[~]$ kill 5124

Jak mogę automatycznie wyodrębnić identyfikator procesu i zabić go w tym samym wierszu?

Lubię to:

[~]$ ps aux | grep 'python csp_build.py' | kill <regex that returns the pid>

3
Uwierz mi! : „D Pierwsza wybrana odpowiedź jest o wiele bardziej złożona niż rozwiązanie, które powiedziałeś w swojej odpowiedzi. Wolę wybrać swoją drogę.
Santosh Kumar

najlepszy sposób, aby sprawdzić, czy proces istnieje: stackoverflow.com/questions/3043978/…
Trevor Boyd Smith

Odpowiedzi:


1397

W bashpowinieneś być w stanie wykonać:

kill $(ps aux | grep '[p]ython csp_build.py' | awk '{print $2}')

Szczegóły dotyczące jego działania są następujące:

  • psDaje listę wszystkich procesów.
  • Te grepfiltry, które opiera się na ciągu wyszukiwania, [p]to trick, aby zatrzymać Cię podniesienie rzeczywistego grepsam proces.
  • Po awkprostu daje ci drugie pole każdej linii, którym jest PID.
  • Te $(x)środki konstrukt wykonać xnastępnie podjąć swoje wyjście i umieścić go w wierszu poleceń. Wyjściem tego pspotoku w powyższej konstrukcji jest lista identyfikatorów procesów, więc otrzymujesz polecenie podobne do kill 1234 1122 7654.

Oto transkrypcja pokazująca go w akcji:

pax> sleep 3600 &
[1] 2225
pax> sleep 3600 &
[2] 2226
pax> sleep 3600 &
[3] 2227
pax> sleep 3600 &
[4] 2228
pax> sleep 3600 &
[5] 2229
pax> kill $(ps aux | grep '[s]leep' | awk '{print $2}')
[5]+  Terminated              sleep 3600
[1]   Terminated              sleep 3600
[2]   Terminated              sleep 3600
[3]-  Terminated              sleep 3600
[4]+  Terminated              sleep 3600

i widać, jak kończy wszystkie podkłady.


Wyjaśniając grep '[p]ython csp_build.py'nieco bardziej szczegółowo:

Kiedy to sleep 3600 &nastąpi ps -ef | grep sleep, masz tendencję do uzyskania dwóch procesów, sleepw tym sleep 3600i grep sleep(ponieważ oba mają sleepw sobie, to nie jest nauka o rakietach).

Jednak ps -ef | grep '[s]leep'nie utworzy w nim procesu sleep, zamiast tego utworzy grep '[s]leep'i oto podstęp: grepnie można go znaleźć, ponieważ szuka wyrażenia regularnego „dowolny znak z klasy znaków [s](która jest s), po której następuje leep.

Innymi słowy, szuka, sleepale proces grep jest tym, grep '[s]leep'czego nie ma sleep.

Kiedy pokazano mi to (przez kogoś tutaj na SO), natychmiast zacząłem go używać, ponieważ

  • to jeden proces mniej niż dodawanie | grep -v grep; i
  • to eleganckie i podstępne, rzadkie połączenie :-)

2
@paxdiablo, czy możesz podać link do tego? Jestem zaskoczony, dlaczego to działa.
glenn jackman

58
Możesz użyć tylko awk - ps aux | awk '/ [b] eam / {print $ 2}' , grep nie jest potrzebne
Yola

20
Lepiej używać tylko pgrep lub pkill
NGix,

2
Jest jeden mały problem - jeśli proces został już zakończony, ta linia killzostanie wypuszczona ze standardowym wyjściemkill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Lionel Chan

5
Zamiast grep '[p]ython csp_build.py'można również użyć: kill $(ps aux | grep 'python csp_build.py' | grep -v grep | awk '{print $2}'). grep -vzwraca niepasujące linie.
usandfriends

138

jeśli masz pkill,

pkill -f csp_build.py

Jeśli chcesz tylko grepować przeciwko nazwie procesu (zamiast pełnej listy argumentów), to przestań -f.


1
Nic się nie stało, kiedy to przetestowałem.
Orjanp,

8
użyj najpierw pgrep, aby zweryfikować poprawność procesu. następnie ponownie użyj pkill na prawidłowym wzorze.
ghostdog74,

18
+1. pgrepi pkillpracuj tak długo, jak będziesz dbał o prawidłowe określenie procesu. Domyślnie dopasowywana jest tylko nazwa procesu , co w tym przypadku prawie na pewno jest po prostu „python”. Użyj, pgrep -f "python csp_build.py"aby dopasować pełne polecenie.
mr. Spuratic

3
Może być konieczne wymuszenie zabójstwa za pomocąpkill -9 -f csp_build.py
studgeek

1
To naprawdę powinna być zaakceptowana i najczęściej głosowana odpowiedź; te inne z całym przebudzeniem są trochę niepotrzebne. Mam nadzieję, że ludzie, którzy znajdą tę stronę, czytają poza pierwszą odpowiedzią.
Jason C

89

Jedna wkładka:

ps aux | grep -i csp_build | awk '{print $2}' | xargs sudo kill -9

  • Wydrukuj kolumnę 2: awk '{print $2}'
  • sudo jest opcjonalne
  • Run kill -9 5124, kill -9 5373etc (kill -15 jest więcej wdzięku, ale nieco wolniej)

Premia:

Mam również 2 funkcje skrótów zdefiniowane w moim pliku .bash_profile (~ / .bash_profile dotyczy systemu OSX, musisz zobaczyć, co działa na twoim komputerze * nix).

  1. słowo kluczowe p
    • Wykazy wszystkie P rocesses zawierających słowa kluczowego
    • Wykorzystanie np p csp_build, p pythonetc

kod bash_profile:

# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}
  1. ka słowo kluczowe
    • K bolączki procesy ll, które mają tego słowa kluczowego
    • Wykorzystanie np ka csp_build, ka pythonetc
    • Opcjonalny np poziom zabitych: ka csp_build 15,ka python 9

kod bash_profile:

# KILL ALL
function ka(){

    cnt=$( p $1 | wc -l)  # total count of processes found
    klevel=${2:-15}       # kill level, defaults to 15 if argument 2 is empty

    echo -e "\nSearching for '$1' -- Found" $cnt "Running Processes .. "
    p $1

    echo -e '\nTerminating' $cnt 'processes .. '

    ps aux  |  grep -i $1 |  grep -v grep   | awk '{print $2}' | xargs sudo kill -klevel
    echo -e "Done!\n"

    echo "Running search again:"
    p "$1"
    echo -e "\n"
}

Przypomnienie - nie zapomnij zrestartować powłoki bash (terminal), aby załadować nowe funkcje. LUB uruchom source ~/.bash_profilew bieżącej powłoce, aby zaimportować nowe funkcje (tak wolę).
a20

Podobnie jak wiele innych odpowiedzi tutaj, monumentalnie cierpi z powodu bezużytecznego użyciagrep . Pamiętaj, że wszystko, co wygląda, grep x | awk '{ y }'jest zwykle lepsze i często bardziej niezawodne, jeśli go awk '/x/ { y }'
zastąpisz

1
@tripleee strona, do której linkujesz, należy do ciebie, prawda? Zauważ, że łączysz to w różnych sekcjach komentarzy. Próbujesz budować SEO?
a20

Nie, nie interesuję się SEO. Mam nadzieję zbudować świadomość.
tripleee

1
.. poprzez link do Twojej witryny, tak jakby była to strona o ustalonym autorytecie. Miły. Ponadto grep jest szybszy .
a20

16
killall -r regexp

-r, --regexp

Interpretuj wzorzec nazwy procesu jako rozszerzone wyrażenie regularne.


15

Spróbuj użyć

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill

Musiałem to trochę zmienić. To zadziałało. Dzięki. :) ps aux | grep 'python csp_build.py' | głowa -1 | cut -d "" -f 5 | xargs kill
Orjanp,

3
ps aux | grep 'python csp_build.py' | awk '{print $2}' | xargs killpracował dla mnie. dzięki
Rasika Perera

Pamiętajcie, dzieci, Awk może zrobić wszystko grep, a większość z nich po prostu i elegancko. Trywialny przypadek grep x y | awk '{ z }'jest zawsze lepiej napisany awk '/x/ { z }' y- patrz także bezużyteczne użyciegrep .
tripleee

11

Możesz używać tylko pkill '^python*' do zabijania procesu wyrażeń regularnych.

Jeśli chcesz zobaczyć, co zabijesz lub znajdziesz przed zabiciem, po prostu użyj pgrep -l '^python*'gdzie -l wypisuje również nazwę procesu. Jeśli nie chcesz używać pkill, użyj tylko:

pgrep '^python*' | xargs kill


8

Użyj pgrep - dostępnego na wielu platformach:

kill -9 `pgrep -f cps_build`

pgrep -f zwróci wszystkie identyfikatory PID z przypadkiem „cps_build”


2
Jeśli tak pgrep, to ty również pkill. Jak zawsze nie używaj,kill -9 chyba że wiesz, dlaczego kill -15(ustawienie domyślne) lub kill -2nie będzie działać.
tripleee

To wygląda na gorszą parafrazę odpowiedzi @ nathanael, która pomija błędne przekierowanie -9i używa odpowiedniej nowoczesnej składni podstawiania poleceń. Poproś o to zamiast tego; choć oczywiście pkillodpowiedź jest lepsza.
tripleee

@tripleee W tym przypadku zabij -9 jest dokładnie tym, czego chcę - zlikwiduj wszystkich przestępców ze skrajnym uprzedzeniem. Ponadto od wielu lat używam kill -9 bez żadnych problemów. Moim zdaniem zawsze będzie obóz purystów kontra obóz realistycznych realizatorów, a ja należę do tych ostatnich (w tej kwestii).
a20

Czy przegapiłeś część „chyba że wiesz dlaczego”? Jestem za robieniem rzeczy, ale jest to jeden z typowych sposobów strzelania sobie w stopę, dopóki nie zrozumiecie, co to -9właściwie znaczy.
tripleee

@tripleee hej tripleee, niedawno odkryłem, że masz rację, zabij -15 to lepszy wybór, ponieważ daje aplikacji szansę na zabicie się z wdziękiem. Odpowiednio zmieniłem kod: stackoverflow.com/a/30486159/163382
a20

6

Zwróci tylko pid

pgrep -f 'process_name'

Aby zabić dowolny proces w jednej linii:

kill -9 $(pgrep -f 'process_name')

lub, jeśli znasz dokładną nazwę procesu, możesz także spróbować pidof:

kill -9 $(pidof 'process_name')

Ale jeśli nie znasz dokładnej nazwy procesu, pgrepbyłoby lepiej.

Jeśli istnieje wiele procesów o tej samej nazwie, a chcesz zabić pierwszy, to:

kill -9 $(pgrep -f 'process_name' | head -1)

Pamiętaj też, że jeśli martwisz się rozróżnianiem wielkości liter, możesz dodać opcję -i, tak jak w grep. Na przykład:

kill -9 $(pgrep -fi chrome)

Więcej informacji na temat sygnałów i pgrep na man 7 signallub man signaliman pgrep


5

możesz to zrobić za pomocą awk i backtics

ps auxf |grep 'python csp_build.py'|`awk '{ print "kill " $2 }'`

2 $ w awk drukuje kolumnę 2, a backtics uruchamia wypisaną instrukcję.

Ale znacznie czystszym rozwiązaniem byłoby przechowywanie przez proces python jego identyfikatora procesu w / var / run, a następnie można po prostu odczytać ten plik i zabić go.


Czy nie zabijesz zatem zarówno procesu 5124, jak i 5373? Myślę, że to nie jest problem.
Orjanp,

nie powinno to stanowić problemu, ale zawsze możesz dodać kolejny grep, aby wykluczyć proces grep: „grep -v grep” między grep i awk
Alexander Kjäll

Testowany z nieco zmodyfikowanym poleceniem. Ale to nie zabiło procesu, tylko wydrukowane zabójstwo <pid>. ps auxf | grep '[p] ython csp_build.py' | awk '{print "kill" 2 $}
Orjanp,

Potrzebne tylko do zamiany wydruku „zabić” 2 $ na system („zabić” 2 $). To działa. :)
Orjanp,

5

Moim zadaniem było zabicie wszystkiego pasującego do wyrażenia regularnego, które jest umieszczone w określonym katalogu (po testach selenu nie wszystko się zatrzymało). To działało dla mnie:

for i in `ps aux | egrep "firefox|chrome|selenium|opera"|grep "/home/dir1/dir2"|awk '{print $2}'|uniq`; do kill $i; done

-9Opcja killjest chyba zbyt agresywne. Nie pozwala im uwolnić zasobów.
Birei

Miły! Jedyny, który bierze pod uwagę fakt, że może istnieć więcej niż jeden proces dopasowywania! Jedna mała uwaga: być może możesz chcieć dodać „grep -v grep” lub coś w tym rodzaju do potoków, aby mieć pewność, że sam proces grep nie pojawi się na liście procesów.
Brad Parks

killakceptuje wiele procesów, więc pętla jest w zasadzie bezużyteczna; i jak zauważono w innym miejscu na tej stronie, nie powinieneś używać, kill -9chyba że wiesz, że proces nie odpowie tylko na kill.
tripleee

usuń -9 nie jest wielką rzeczą, dlaczego głosować negatywnie. Lepiej zredaguj odpowiedź.
Serge

5

Aby zabić proces według słowa kluczowego midori, na przykład:

kill -SIGTERM $(pgrep -i midori)


3

Metoda wykorzystująca tylko awk(i ps):

ps aux | awk '$11" "$12 == "python csp_build.py" { system("kill " $2) }'

Używając testów równości łańcuchów, zapobiegam dopasowaniu samego procesu.


Z jakiegoś powodu nie dostaję trafienia w „python csp_build.py”. Ale sam „python” uderza.
Orjanp,

3
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15

Nie można dać +1 ze względu na dzienny limit, ale warto skorzystać psz -oopcji.
P Shved

ps nie dają mi wiele. [~] $ ps PID TTY TIME CMD 6365 pkt / 6 00:00:00 ps 29112 pkt / 6 00:00:00 bash
Orjanp

3

Daj -f, aby pkill

pkill -f /usr/local/bin/fritzcap.py

dokładna ścieżka pliku .py to

# ps ax | grep fritzcap.py
 3076 pts/1    Sl     0:00 python -u /usr/local/bin/fritzcap.py -c -d -m

2

Zacząłem używać czegoś takiego:

kill $(pgrep 'python csp_build.py')

1

Zabij nasze własne procesy rozpoczęte od wspólnego PPID jest dość często, pkill związany z –Pflagą jest dla mnie zwycięzcą. Na przykładzie @ ghostdog74:

# sleep 30 &                                                                                                      
[1] 68849
# sleep 30 &
[2] 68879
# sleep 30 &
[3] 68897
# sleep 30 &
[4] 68900
# pkill -P $$                                                                                                         
[1]   Terminated              sleep 30
[2]   Terminated              sleep 30
[3]-  Terminated              sleep 30
[4]+  Terminated              sleep 30

1

Nie potrzebujesz przełącznika użytkownika dla ps.

kill `ps ax | grep 'python csp_build.py' | awk '{print $1}'`

1

W niektórych przypadkach chciałbym jednocześnie zabijać procesy w ten sposób:

Sleep ~ spać 1000 i
[1] 25410
Sleep ~ spać 1000 i
[2] 25415
Sleep ~ spać 1000 i
[3] 25421
P ~ pidof spać
25421 25415 25410
➜ ~ zabij `pidof sleep`
[2] - 25415 zakończyło sen 1000                                                             
[1] - 25410 zakończyło sen 1000
[3] + 25421 zakończyło sen 1000

Ale myślę, że jest to trochę niestosowne w twoim przypadku (może być uruchomione w tle python a, python b, python x ...)


1

Jeśli pkill -f csp_build.pynie zabije procesu, możesz dodać, -9aby wysłać sygnał zabicia, który nie zostanie zignorowany. to znaczypkill -9 -f csp_build.py


1

Rozwiązaniem byłoby filtrowanie procesów z dokładnym wzorcem, parsowanie pid i tworzenie listy argumentów do wykonywania procesów kill:

ps -ef  | grep -e <serviceNameA> -e <serviceNameB> -e <serviceNameC> |
awk '{print $2}' | xargs sudo kill -9

Wyjaśnienie z dokumentacji:

ps narzędzie wyświetla wiersz nagłówka, a następnie wiersze zawierające informacje o wszystkich procesach, które mają kontrolujące terminale.

-e Wyświetl informacje o procesach innych użytkowników, w tym o procesach

-f Wyświetla identyfikator użytkownika, identyfikator pid, identyfikator nadrzędny, ostatnie użycie procesora, rozpoczęcie procesu

Narzędzie grep przeszukuje dane pliki wejściowe, wybierając wiersze, które

-e wzorzec, --regexp = wzorzec Określ wzorzec używany podczas wyszukiwania danych wejściowych: linia wejściowa jest wybierana, jeśli pasuje do któregokolwiek z określonych wzorców. Ta opcja jest najbardziej użyteczna, gdy wiele opcji -e jest używanych do określenia wielu wzorów lub gdy wzór zaczyna się od myślnika (`- ').

xargs - konstruuj listy argumentów i uruchamiaj narzędzie

kill - kończy lub sygnalizuje proces

sygnał numer 9 - KILL (nie do złapania, nie do zapomnienia)

Przykład :

ps -ef  | grep -e node -e loggerUploadService.sh - -e applicationService.js |
awk '{print $2}' | xargs sudo kill -9

0

Używam tego, by zabić Firefoksa, gdy jest on zatrzaskiwany przez skrypt i bicie procesora :) Zamień „Firefox” na aplikację, którą chcesz umrzeć. Jestem w powłoce Bash - OS X 10.9.3 Darwin.

kill -Hup $(ps ux | grep Firefox | awk 'NR == 1 {next} {print $2}' | uniq | sort)


Wymiana grep Firefox | awk 'NR == 1 { next } ...'z awk 'NR == 1 || $11 !~ /Firefox/ { next } ...'oszczędza nie tylko proces, ale również poprawia precyzję. To nie jest trudne, aby pozbyć się sort | uniqw czystej Awk albo (podczas gdy oczywiście uniq | sortjest po prostu źle - będzie przegap żadnych duplikatów, które nie sąsiadują ze sobą, a ukryć błąd, niepotrzebnie sortowania wyjście z uniq).
tripleee

0

Używam gkill processname, gdzie gkill to następujący skrypt:

cnt=`ps aux|grep $1| grep -v "grep" -c`
if [ "$cnt" -gt 0 ]
then
    echo "Found $cnt processes - killing them"
    ps aux|grep $1| grep -v "grep"| awk '{print $2}'| xargs kill
else
    echo "No processes found"
fi

UWAGA: NIE zabije procesów, które mają „grep” w swoich wierszach poleceń.


1
Podobnie jak wiele, wiele innych wynalazków jaków, jest to usiane bezużytecznym użyciemgrep i innych popularnych antypatrownic skryptów powłoki.
tripleee

-1

Przyda się następujące polecenie:

kill $(ps -elf | grep <process_regex>| awk {'print $4'})

na przykład., ps -elf | grep top

    0 T ubuntu    6558  6535  0  80   0 -  4001 signal 11:32 pts/1    00:00:00 top
    0 S ubuntu    6562  6535  0  80   0 -  2939 pipe_w 11:33 pts/1    00:00:00 grep --color=auto top

kill -$(ps -elf | grep top| awk {'print $4'})

    -bash: kill: (6572) - No such process
    [1]+  Killed                  top

Jeśli proces nadal jest zablokowany, użyj rozszerzenia „-9”, aby wykonać hardkill w następujący sposób:

kill -9 $(ps -elf | grep top| awk {'print $4'})

Mam nadzieję, że to pomaga ...!


-1

Znajdź i zabij wszystkie procesy w jednej linii w bash.

kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})
  • ps -ef | grep '<exe_name>'- Podaje listę szczegółów uruchomionego procesu (uname, pid itp.), Które pasują do wzorca. Lista wyników zawiera to greppolecenie, które również je wyszukuje. Teraz zabijanie musimy zignorować ten grepproces dowodzenia.
  • ps -ef | grep '<exec_name>' | grep -v 'grep'- Dodanie kolejnego grep z -v 'grep'usuwa bieżący proces grep.
  • Następnie za pomocą awkpobierz sam identyfikator procesu.
  • Następnie trzymaj to polecenie w środku $(...)i przekaż je killkomendom, aby zabić cały proces.

-1

Możesz użyć poniższego polecenia, aby wyświetlić pid polecenia. Użyj top lub lepiej użyj htop, aby wyświetlić cały proces w systemie Linux. Tutaj chcę zabić proces o nazwie

ps -ef | grep '/usr/lib/something somelocation/some_process.js'  | grep -v grep | awk '{print $2}'

I sprawdź pid. To musi być właściwe. Aby je zabić, użyj polecenia kill.

sudo kill -9 `ps -ef | grep '/usr/lib/something somelocation/some_process.js'  | grep -v grep | awk '{print $2}'`

Np .: - pochodzi z listy procesów htop.

sudo kill -9 `ps -ef | grep '<process>'  | grep -v grep | awk '{print $2}'`

To rozwiązuje moje problemy. Zawsze przygotuj się na ponowne uruchomienie procesu, jeśli przypadkowo go zabijesz.

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.