使用 bash 和正则表达式在一行中查找并终止进程
我在编程时经常需要杀死一个进程。
我现在的做法是:
[~]$ 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>
I often need to kill a process during programming.
The way I do it now is:
[~]$ 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
How can I extract the process id automatically and kill it in the same line?
Like this:
[~]$ ps aux | grep 'python csp_build.py' | kill <regex that returns the pid>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
在
bash
中,仅使用问题(1)中列出的基本工具,您应该能够执行以下操作:其工作原理的详细信息如下:
ps
为您提供所有进程的列表。grep
根据您的搜索字符串进行过滤,[p]
是一种阻止您获取实际grep
进程本身的技巧。awk
只是为您提供每行的第二个字段,即 PID。$(x)
构造意味着执行x
然后获取其输出并将其放在命令行上。上面构造中的ps
管道的输出是进程 ID 列表,因此您最终会得到类似kill 1234 1122 7654
的命令。这是显示其实际操作的文字记录:
您可以看到它终止了所有睡眠者。
更详细地解释
grep '[p]ython csp_build.py'
位:当您执行sleep 3600 &
后跟ps -ef | grep sleep
,您往往会得到两个个带有sleep
的进程,sleep 3600
和grep sleep< /code> (因为它们都有
睡眠
,这不是火箭科学)。但是,ps -ef | grep '[s]leep' 不会创建一个包含
sleep
的grep
进程,而是使用命令grep '[ 创建一个进程s]leep'
这就是棘手的一点:grep
找不到那个,因为它正在寻找正则表达式“字符类[s] 中的任何字符”
(基本上就是s
),然后是leep
换句话说,它正在寻找
sleep
但 grep 过程是sleep
。 code>grep '[s]leep' 其中没有文本sleep
当我看到这个(由 SO 上的某人)时,我立即开始使用它,因为。
| grep -v grep
少了一个过程,而且(1); 不仅限于使用这些基本工具,有一个漂亮的
pgrep
命令,它可以根据特定条件查找进程(当然,假设您的系统上有它) 。例如,您可以使用 pgrep sleep 输出所有 sleep 命令的进程 ID(默认情况下,它与进程名称匹配)。如果您想匹配整个命令行,如
ps
所示,您可以执行pgrep -f 'sleep 9999'
之类的操作。顺便说一句,如果您执行
pgrep pgrep
,它不会列出自身,因此在这种情况下不需要上面显示的棘手过滤方法。您可以使用
-a
显示完整的进程名称来检查这些进程是否是您感兴趣的进程。您还可以使用-u
或-U
将范围限制为您自己的进程(或一组特定的用户)。有关更多选项,请参阅pgrep
/pkill
的man
页面。一旦您满意,它只会显示您感兴趣的进程,然后您可以使用具有相同参数的
pkill
向所有这些进程发送信号。In
bash
, using only the basic tools listed in your question(1), you should be able to do:Details on its workings are as follows:
ps
gives you the list of all the processes.grep
filters that based on your search string,[p]
is a trick to stop you picking up the actualgrep
process itself.awk
just gives you the second field of each line, which is the PID.$(x)
construct means to executex
then take its output and put it on the command line. The output of thatps
pipeline inside that construct above is the list of process IDs so you end up with a command likekill 1234 1122 7654
.Here's a transcript showing it in action:
and you can see it terminating all the sleepers.
Explaining the
grep '[p]ython csp_build.py'
bit in a bit more detail: when you dosleep 3600 &
followed byps -ef | grep sleep
, you tend to get two processes withsleep
in it, thesleep 3600
and thegrep sleep
(because they both havesleep
in them, that's not rocket science).However,
ps -ef | grep '[s]leep'
won't create agrep
process withsleep
in it, it instead creates one with the commandgrep '[s]leep'
and here's the tricky bit: thegrep
doesn't find that one, because it's looking for the regular expression "any character from the character class[s]
(which is basically justs
) followed byleep
.In other words, it's looking for
sleep
but the grep process isgrep '[s]leep'
which doesn't have the textsleep
in it.When I was shown this (by someone here on SO), I immediately started using it because
| grep -v grep
; and(1) If you're not limited to using those basic tools, there's a nifty
pgrep
command which will find processes based on certain criteria (assuming you have it available on your system, of course).For example, you can use
pgrep sleep
to output the process IDs for allsleep
commands (by default, it matches the process name). If you want to match the entire command line as shown inps
, you can do something likepgrep -f 'sleep 9999'
.As an aside, it doesn't list itself if you do
pgrep pgrep
, so the tricky filter method shown above is not necessary in this case.You can check that the processes are the ones you're interested in by using
-a
to show the full process names. You can also limit the scope to your own processes (or a specific set of users) with-u
or-U
. See theman
page forpgrep
/pkill
for more options.Once you're satisfied it will only show the processes you're interested in, you can then use
pkill
with the same parameters to send a signal to all those processes.如果你有 pkill,
如果你只想对进程名称(而不是完整的参数列表)进行 grep,那么请忽略
-f
。if you have pkill,
If you only want to grep against the process name (instead of the full argument list) then leave off
-f
.一行:
ps aux | grep -i csp_build | grep -i csp_build | grep -i csp_build | 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 代码:
ka csp_build
、ka python
等ka csp_build 15
、ka python 9
bash_profile代码:
One liner:
ps aux | grep -i csp_build | awk '{print $2}' | xargs sudo kill -9
awk '{print $2}'
sudo
is optionalkill -9 5124
,kill -9 5373
etc (kill -15 is more graceful but slightly slower)Bonus:
I also have 2 shortcut functions defined in my .bash_profile
(~/.bash_profile is for osx, you have to see what works for your *nix machine).
p csp_build
,p python
etcbash_profile code:
ka csp_build
,ka python
etcka csp_build 15
,ka python 9
bash_profile code:
将进程名称模式解释为扩展的正则表达式。
Interpret process name pattern as an extended regular expression.
这将仅返回 pid
因此,要在一行中终止任何进程:
或者,如果您知道进程的确切名称,您也可以尝试 pidof:
但是,如果您不知道进程的确切名称,pgrep 会更好。
如果有多个同名进程正在运行,并且您想杀死第一个进程,那么:
还要注意,如果您担心区分大小写,那么您可以像在 grep 中一样添加 -i 选项。例如:
有关信号和 pgrep 的更多信息,请参见
man 7 signal
或man signal
和man pgrep
This will return the pid only
So to kill any process in one line:
or, if you know the exact name of the process you can also try pidof:
But, if you do not know the exact name of the process,
pgrep
would be better.If there is multiple process running with the same name, and you want to kill the first one then:
Also to note that, if you are worried about case sensitivity then you can add -i option just like in grep. For example:
More info about signals and pgrep at
man 7 signal
orman signal
andman pgrep
尝试使用
Try using
您只能使用
pkill '^python*'
进行正则表达式进程终止。如果您想在杀死之前查看要杀死或找到的内容,只需使用 pgrep -l '^python*' ,其中 -l 还输出进程的名称。如果你不想使用
pkill
,仅使用:pgrep '^python*' | xargs 杀死
You may use only
pkill '^python*'
for regex process killing.If you want to see what you gonna kill or find before killing just use
pgrep -l '^python*'
where -l outputs also name of the process. If you don't want to usepkill
, use just:pgrep '^python*' | xargs kill
使用 pgrep - 在许多平台上可用:
pgrep -f 将返回与“cps_build”一致的所有 PID
Use pgrep - available on many platforms:
pgrep -f will return all PIDs with coincidence "cps_build"
解决方案将使用精确的模式过滤进程,解析pid,并构造一个用于执行终止进程的参数列表:
来自文档的解释:
-e 显示有关其他用户进程的信息,包括那些
示例:
The solution would be filtering the processes with exact pattern , parse the pid, and construct an argument list for executing kill processes:
Explanation from documenation:
-e Display information about other users' processes, including those
Example:
您可以使用 awk 和 backtics $2 in awk 打印第 2 列来完成此操作
,并且 backtics 运行打印的语句。
但更简洁的解决方案是让 python 进程将其进程 ID 存储在 /var/run 中,然后您可以简单地读取该文件并杀死它。
you can do it with awk and backtics
$2 in awk prints column 2, and the backtics runs the statement that's printed.
But a much cleaner solution would be for the python process to store it's process id in /var/run and then you can simply read that file and kill it.
我的任务是杀死放置在特定目录中的所有匹配正则表达式的内容(在硒测试之后,并非所有内容都停止)。这对我有用:
My task was kill everything matching regexp that is placed in specific directory (after selenium tests not everything got stop). This worked for me:
这里有很多好的答案 - 我使用了OP接受的答案。只需添加有关
pkill
和pgrep
的小警告。正如您可能从其手册页中看到的,在您的操作系统上,某些操作系统有 15-进程名称的字符限制。-f
选项在我的操作系统上解决了这个问题,但在找到该选项之前我遇到了麻烦!Lots of good answers here - I used the answer accepted by the OP. Just adding a small caveat note about
pkill
andpgrep
. As you might see from their manual pages, on your OS, some OS's have a 15-character limit on the process name. The-f
option gets around that on my OS, but I was in trouble until I found that option!通过关键字
midori
终止进程,例如:kill -SIGTERM $(pgrep -i midori)
To kill process by keyword
midori
, for example:kill -SIGTERM $(pgrep -i midori)
仅使用
awk
(和ps
)的方法:通过使用字符串相等性测试,我可以防止匹配此过程本身。
A method using only
awk
(andps
):By using string equality testing I prevent matching this process itself.
给 -f 给 pkill
.py 文件的确切路径是
Give -f to pkill
exact path of .py file is
我开始使用这样的东西:
I started using something like this:
将杀死模式 PATTERN 匹配的所有进程。使用 -f 选项,将考虑整个命令行(即包括参数)。如果没有 -f 选项,则仅考虑命令名称。
Will kill all the processes that the pattern PATTERN matches. With the -f option, the whole command line (i.e. including arguments) will be taken into account. Without the -f option, only the command name will be taken into account.
ps 不需要用户切换。
You don't need the user switch for ps.
在某些情况下,我想像这样同时终止进程:
但是,我认为这在你的情况下有点不合适。(可能后台正在运行 python a、python b、python x...。 )
In some cases, I'd like kill processes simutaneously like this way:
But, I think it is a little bit inappropriate in your case.(May be there are running python a, python b, python x...in the background.)
在 bash 的一行中查找并杀死所有进程。
grep
命令,该命令也可对其进行搜索。现在为了杀死我们需要忽略这个 grep 命令过程。-v 'grep'
添加另一个 grep 会删除当前的 grep 进程。$(...)
中并将其传递给kill
命令,以终止所有进程。Find and kill all the processes in one line in bash.
ps -ef | grep '<exe_name>'
- Gives the list of running process details (uname, pid, etc ) which matches the pattern. Output list includes thisgrep
command also which searches it. Now for killing we need to ignore thisgrep
command process.ps -ef | grep '<exec_name>' | grep -v 'grep'
- Adding another grep with-v 'grep'
removes the current grep process.awk
get the process id alone.$(...)
and pass it tokill
command, to kill all process.如果 pkill -f csp_build.py 没有终止进程,您可以添加 -9 来发送不会被忽略的终止信号。即 pkill -9 -f csp_build.py
If
pkill -f csp_build.py
doesn't kill the process you can add-9
to send a kill signall which will not be ignored. i.e.pkill -9 -f csp_build.py
使用
ps
命令的-C
标志第一种情况,简单的命令
因此,如果您通过标准 shebang 运行脚本并通过他的名字调用它们:
您可能会发现它们
所以
可能就足够了。
第二种情况,搜索 cmd
更强一点,但仍然比这个问题中的大多数其他答案快得多...
如果您不知道这是运行的,或者如果您运行它们,
您可以通过运行找到它们:
然后使用 sed:
Using
-C
flag ofps
command1st case, simple command
So if you run your script by standard shebang and calling them by his name:
You may find them whith
So
may be enough.
2nd case, search for cmd
A little more strong, but still a lot quicker than most other answer in this SO question...
If you don't know ho this is run, or if you run them by
You may find them by running:
Then using
sed
:基于 https://stackoverflow.com/a/3510879/15603477 答案。小幅优化。
通过使用
tr -s ' '
将多个空格(如果有)压缩为 1 个空格。如果您遇到
不允许操作
,请按照此>>> https://unix. stackexchange.com/questions/89316/how-to-kill-a-process-that-says-operation-not-permissed-when-attemptedBased on https://stackoverflow.com/a/3510879/15603477 answer. Minor optimization.
By using
tr -s ' '
to squeeze multi whitespaces (if have) to 1 white space.In case you encountered
Operation not permitted
follow this>> https://unix.stackexchange.com/questions/89316/how-to-kill-a-process-that-says-operation-not-permitted-when-attempted终止从公共 PPID 启动的我们自己的进程非常频繁,与
-P
标志关联的 pkill 对我来说是赢家。使用 @ghostdog74 示例:Kill our own processes started from a common PPID is quite frequently, pkill associated to the
–P
flag is a winner for me. Using @ghostdog74 example :当 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)
I use this to kill Firefox when it's being script slammed and cpu bashing :)
Replace 'Firefox' with the app you want to die. I'm on the 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 是以下脚本:
注意:它不会杀死命令行中包含“grep”的进程。
I use
gkill processname
, where gkill is the following script:NOTE: it will NOT kill processes that have "grep" in their command lines.
如果您想主要在
awk
中完成,请尝试if you wanna do it mostly within
awk
, try在Mac上,我尝试了从此线程中截取的每一个片段来杀死卡住并阻止注销的slack,但唯一有效的方法是打开ActivityMonitor,找到slack和4个slackhelper进程并强制退出它们。
on Mac, I tried every snipped from this thread to kill slack that got stuck and prevented logout, but the only thing that worked was to open ActivityMonitor, find there slack and 4 slackhelper processes and forcefully quit them all.
以下命令会很方便:
kill $(ps -elf | grep| awk {'print $4'})
例如,
ps -elf | ps -elf | ps -elf | ps -elf | ps -elf | ps -elf grep top
kill -$(ps -elf | grep top| awk {'print $4'})
如果进程仍然卡住,请使用“-9”扩展名来hardkill,如下:
kill -9 $(ps -elf | grep top| awk {'print $4'})
希望有帮助...!
The following command will come handy:
kill $(ps -elf | grep <process_regex>| awk {'print $4'})
eg.,
ps -elf | grep top
kill -$(ps -elf | grep top| awk {'print $4'})
If the process is still stuck, use "-9" extension to hardkill, as follows:
kill -9 $(ps -elf | grep top| awk {'print $4'})
Hope that helps...!