簡體   English   中英

使用 bash 和正則表達式在一行中查找並終止進程

[英]Find and kill a process in one line using bash and regex

我經常需要在編程過程中殺死一個進程。

我現在的做法是:

[~]$ 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

如何自動提取進程 ID 並在同一行中將其殺死?

像這樣:

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

bash中,您應該能夠:

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

其運作詳情如下:

  • ps為您提供所有進程的列表。
  • 基於您的搜索字符串的grep過濾器[p]是阻止您獲取實際grep進程本身的技巧。
  • awk只為您提供每行的第二個字段,即 PID。
  • $(x)構造意味着執行x然后獲取其輸出並將其放在命令行上。 上面構造中的ps管道的輸出是進程 ID 列表,因此您最終會得到類似kill 1234 1122 7654的命令。

這是一個顯示它在行動的成績單:

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

你可以看到它終止了所有的睡眠者。


更詳細地解釋grep '[p]ython csp_build.py'位:

當你做sleep 3600 &然后是ps -ef | grep sleep ps -ef | grep sleep ,你往往會得到兩個帶有sleep的進程, sleep 3600grep sleep (因為它們都有sleep ,這不是火箭科學)。

但是, ps -ef | grep '[s]leep' ps -ef | grep '[s]leep'不會創建一個包含sleep的進程,而是創建grep '[s]leep' ,這是一個棘手的問題: grep找不到它,因為它正在尋找正則表達式“any來自字符類[s]的字符(即s ),后跟leep

換句話說,它正在尋找sleep ,但 grep 進程是grep '[s]leep' ,其中沒有sleep

當我看到這個(這里的某人)時,我立即開始使用它,因為

  • 比添加少一個過程| grep -v grep | grep -v grep ;
  • 它優雅狡猾,是一種罕見的組合:-)

如果你有 pkill,

pkill -f csp_build.py

如果您只想針對進程名稱(而不是完整的參數列表)進行 grep,則不要使用-f

一個班輪:

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

  • 打印出第 2 列: awk '{print $2}'
  • sudo是可選的
  • 運行kill -9 5124kill -9 5373等(kill -15 更優雅但稍慢)

獎金:

我還在我的 .bash_profile 中定義了 2 個快捷方式函數(~/.bash_profile 用於 osx,您必須查看適用於您的 *nix 機器的方法)。

  1. p關鍵字
    • 列出所有包含關鍵字的進程
    • 用法例如: p csp_buildp python

bash_profile 代碼:

# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}
  1. ka關鍵字
    • 殺死所有有這個關鍵字進程
    • 用法例如: ka csp_buildka python
    • 可選的殺戮級別,例如: ka csp_build 15ka python 9

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"
}
killall -r regexp

-r, --regexp

將進程名稱模式解釋為擴展的正則表達式。

這將只返回 pid

pgrep -f 'process_name'

所以要在一行中殺死任何進程:

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

或者,如果您知道進程的確切名稱,您也可以嘗試 pidof:

kill -9 $(pidof 'process_name')

但是,如果您不知道進程的確切名稱, pgrep會更好。

如果有多個進程以相同的名稱運行,並且您想殺死第一個進程,那么:

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

還要注意的是,如果您擔心區分大小寫,那么您可以像在 grep 中一樣添加 -i 選項。 例如:

kill -9 $(pgrep -fi chrome)

有關信號和 pgrep 的更多信息,請參見man 7 signalman signal and man pgrep

嘗試使用

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

您只能使用pkill '^python*'來殺死正則表達式進程。

如果您想在殺死之前查看要殺死或找到的內容,只需使用pgrep -l '^python*'其中 -l 還輸出進程的名稱。 如果您不想使用pkill ,請使用:

pgrep '^python*' | xargs kill

使用 pgrep - 在許多平台上可用:

kill -9 `pgrep -f cps_build`

pgrep -f 將返回所有符合“cps_build”的PID

解決方案是過濾具有精確模式的進程,解析 pid,並構造一個參數列表來執行終止進程:

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

文檔說明

ps實用程序顯示一個標題行,然后是包含有關具有控制終端的所有進程的信息的行。

-e顯示有關其他用戶進程的信息,包括那些

-f顯示 uid、pid、父 pid、最近的 CPU 使用率、進程啟動

grep實用程序搜索任何給定的輸入文件,選擇符合以下條件的行

-e pattern, --regexp=pattern 指定在搜索輸入期間使用的模式:如果輸入行匹配任何指定的模式,則選擇該輸入行。 當使用多個 -e 選項指定多個模式時,或者當模式以破折號 (`-') 開頭時,此選項最有用。

xargs - 構造參數列表並執行實用程序

kill - 終止或通知進程

9號信號 - KILL(不可捕獲,不可忽略的殺戮)

示例

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

你可以用 awk 和 backtics 來做

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

awk 中的 $2 打印第 2 列,並且 backtics 運行打印的語句。

但是一個更干凈的解決方案是讓 python 進程將它的進程 ID 存儲在 /var/run 中,然后你可以簡單地讀取該文件並殺死它。

我的任務是殺死與放置在特定目錄中的正則表達式匹配的所有內容(在硒測試之后,並非所有內容都停止了)。 這對我有用:

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

通過關鍵字midori殺死進程,例如:

kill -SIGTERM $(pgrep -i midori)

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

給 -f 給 pkill

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

.py 文件的確切路徑是

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

僅使用awk (和ps )的方法:

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

通過使用字符串相等測試,我防止匹配此過程本身。

這里有很多好的答案 - 我使用了 OP 接受的答案。 只需添加一個關於pkillpgrep的小警告說明。 正如您可能從他們的手冊頁中看到的那樣,在您的操作系統上,某些操作系統的進程名稱限制為 15 個字符。 -f選項在我的操作系統上解決了這個問題,但在找到該選項之前我遇到了麻煩!

我開始使用這樣的東西:

kill $(pgrep 'python csp_build.py')

您不需要 ps 的用戶開關。

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

在某些情況下,我想像這樣同時殺死進程:

➜  ~  sleep 1000 &
[1] 25410
➜  ~  sleep 1000 &
[2] 25415
➜  ~  sleep 1000 &
[3] 25421
➜  ~  pidof sleep
25421 25415 25410
➜  ~  kill `pidof sleep`
[2]  - 25415 terminated  sleep 1000                                                             
[1]  - 25410 terminated  sleep 1000
[3]  + 25421 terminated  sleep 1000

但是,我認為這在你的情況下有點不合適。(可能在后台運行 python a、python b、python x ......)

如果pkill -f csp_build.py沒有終止進程,您可以添加-9以發送不會被忽略的終止信號。 pkill -9 -f csp_build.py

殺死我們自己的進程從一個常見的PPID開始是相當頻繁的,與–P標志相關聯的pkill對我來說是贏家。 使用@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

當 Firefox 被腳本抨擊和 CPU 抨擊時,我用它來殺死 Firefox :) 用你想死的應用程序替換“Firefox”。 我在 Bash shell - OS X 10.9.3 Darwin 上。

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

我使用gkill processname ,其中 gkill 是以下腳本:

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

注意:它不會殺死命令行中包含“grep”的進程。

使用ps命令的-C標志

-C cmdlist Select by command name. This selects the processes whose executable name is given in cmdlist.

第一種情況,簡單的命令

因此,如果您通過標准 shebang運行腳本並以他的名字調用它們:

/path/to/csp_build.py

你可能會發現他們

ps -C csp_build.py

所以

kill $(ps -C csp_build.py ho pid)

可能就夠了。

第二種情況,搜索 cmd

更強一點,但仍然比這個 SO 問題中的大多數其他答案要快得多......

如果你不知道這是運行的,或者如果你運行它們

python csp_build.py
python3 csp_build.py
python /path/to/csp_build.py

您可以通過運行找到它們:

ps -C python,python3,csp_build.py who pid,cmd | grep csp_build.py

然后使用sed

kill $(ps -C python,python3,csp_build.py who pid,cmd |
    sed -ne '/csp_build.py/s/^ *\([0-9]\+\) .*$/\1/p')

基於https://stackoverflow.com/a/3510879/15603477的回答。 小優化。

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

通過使用tr -s ' '將多個空格(如果有)壓縮到 1 個空格。

如果您遇到Operation not permitted請遵循此>> https://unix.stackexchange.com/questions/89316/how-to-kill-a-process-that-says-operation-not-permitted-when-attempted

如果您想主要awk內完成,請嘗試

  for i in $(jot 5); do 
 (python3 -c 'import sys; [ print(_) for _ in sys.stdin ]' ) & done; 
  
  sleep 1; ps aux | {m,g}awk '

       /[p]ython/ { 
              _=(_)" "$2 
       } END { 
           system("echo \47 kill "(_)" \47")
           system(      "kill -9 " _) }'


[302] 14236
[303] 14237
[304] 14238
[305] 14239
[306] 14240
[303]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[305]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[304]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[302]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[306]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
 
 kill  14239 14237 14236 14240 14238 
 
[305]    killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[303]    killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[306]  + killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[304]  - killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[302]  + killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )

對於基本 bash 版本

殺死 $(pidof my_process)

以下命令將派上用場:

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

例如, ps -elf | grep top 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

如果進程仍然卡死,使用“-9”擴展hardkill,如下:

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

希望對您有所幫助...!

在 bash 中的一行中查找並殺死所有進程。

kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})
  • ps -ef | grep '<exe_name>' ps -ef | grep '<exe_name>' - 提供與模式匹配的正在運行的進程詳細信息(uname、pid 等)列表。 輸出列表包括這個grep命令也可以搜索它。 現在為了殺死我們需要忽略這個grep命令進程。
  • ps -ef | grep '<exec_name>' | grep -v 'grep' ps -ef | grep '<exec_name>' | grep -v 'grep' - 使用-v 'grep'添加另一個 grep 會刪除當前的 grep 進程。
  • 然后使用awk單獨獲取進程 ID。
  • 然后將此命令保留在$(...)中並將其傳遞給kill命令,以殺死所有進程。

您可以使用以下命令列出命令的 pid。 使用 top 或更好地使用 htop 查看 linux 中的所有進程。 在這里我想殺死一個名為

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

並驗證pid。 它必須是正確的。要殺死它們,請使用 kill 命令。

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

例如:- 來自 htop 進程列表。

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

這解決了我的問題。 如果您不小心殺死了一個進程,請始終准備好重新啟動進程。

我不喜歡純粹根據 grep 的盲目結果來殺死東西——如果我錯誤地匹配了超出預期的內容怎么辦?

我知道這會被命令行純粹主義者否決,但我更喜歡這種情況下的交互式過濾器,例如pick(apt-get install pick)。 使用這種工具,過濾后的結果會在您鍵入時顯示,因此您可以准確地看到當您按 Enter 時會被殺死的內容。

因此,單線將成為

function killpick { ps ax | pick -q "$1" | awk  '{print $1}' | xargs kill -9; }

killpick 本身提供了一個帶有增量過濾的選擇器,可選參數為過濾器提供了一個起始字符串。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM