[英]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 3600
和grep 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
awk '{print $2}'
sudo
是可選的kill -9 5124
, kill -9 5373
等(kill -15 更優雅但稍慢)我還在我的 .bash_profile 中定義了 2 個快捷方式函數(~/.bash_profile 用於 osx,您必須查看適用於您的 *nix 機器的方法)。
p csp_build
, p python
等bash_profile 代碼:
# FIND PROCESS
function p(){
ps aux | grep -i $1 | grep -v grep
}
ka csp_build
, ka python
等ka csp_build 15
, ka 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 signal
或man 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 接受的答案。 只需添加一個關於pkill
和pgrep
的小警告說明。 正如您可能從他們的手冊頁中看到的那樣,在您的操作系統上,某些操作系統的進程名稱限制為 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)
可能就夠了。
更強一點,但仍然比這個 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.