如何检查进程ID(PID)是否存在

在bash脚本中,我想要执行以下操作(使用伪代码):

if [ a process exists with $PID ]; then kill $PID fi 

条件语句的恰当expression是什么?

要检查进程的存在,请使用

 kill -0 $PID 

但就像@unwind所说的那样,如果你要杀了它,只是

 kill $PID 

或者你将有一个竞争条件。

如果你想忽略kill的文本输出,并根据退出代码做一些事情,你可以

 if ! kill $PID > /dev/null 2>&1; then echo "Could not send SIGTERM to process $PID" >&2 fi 

最好的方法是:

 if ps -p $PID > /dev/null then echo "$PID is running" # Do something knowing the pid exists, ie the process with $PID is running fi 

问题在于:

 kill -0 $PID 

是退出代码将是非零即使该pid正在运行,你没有权限杀死它。 例如:

 kill -0 1 

 kill -0 $non-running-pid 

有一个普通用户不可区分的(非零)退出代码,但init进程(PID 1)当然在运行。

讨论

如果testing的主体是“杀人”,那么讨论杀戮和竞赛条件的答案是完全正确的。 我来找一般的“ 你怎么testing一个PID在bash中存在 ”。

/ proc方法很有趣,但从某种意义上讲,打破了“ps”命令抽象的精神,也就是说你不需要去看/ proc,因为如果Linus决定调用“exe”文件呢?

 if [ -e /proc/$PID ] 

要么

 if [ -n "$(ps -p $PID -o pid=)" ] 

在后一种forms中, -o pid=是只显示没有标题的进程ID列的输出格式。 非空string运算符-n 需要引号才能给出有效的结果。

ps命令与-p $PID可以做到这一点:

 $ ps -p 3531 PID TTY TIME CMD 3531 ? 00:03:07 emacs 

你有两种方法:

让我们开始在我的笔记本电脑中寻找一个特定的应用程序:

 [root@pinky:~]# ps fax | grep mozilla 3358 ? S 0:00 \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox 16198 pts/2 S+ 0:00 \_ grep mozilla 

所有示例现在将查找PID 3358。

第一种方法 :在第二列中运行“ps aux”和grep作为PID。 在这个例子中,我寻找Firefox,然后是PID:

 [root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358 3358 

所以你的代码将是:

 if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then kill $PID fi 

第二种方法 :只要在/proc/$PID目录中找一些东西。 我在这个例子中使用“exe”,但是你可以使用其他的东西。

 [root@pinky:~]# ls -l /proc/3358/exe lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash 

所以你的代码将是:

 if [ -f /proc/$PID/exe ]; then kill $PID fi 

顺便说一句:什么错了kill -9 $PID || true kill -9 $PID || true


编辑:

经过几个月的思考(大约24 …)我给这里的原始想法是一个很好的黑客,但非常不可移植。 虽然它教导了Linux的一些实现细节,但它将无法在Mac,Solaris或* BSD上运行。 它甚至可能会在未来的Linux内核上失败。 请按照其他回复中的描述使用“ps”。

我认为这是一个不好的解决scheme,这对于竞争条件是开放的。 如果这个过程在你的testing和你的杀手之间死掉了怎么办? 然后杀死将失败。 那么为什么不试试在所有情况下杀死,并检查其返回值,以了解它是怎么回事?

好像你想要的

 wait $PID 

$pid完成时将返回。

否则,你可以使用

 ps -p $PID 

检查过程是否还活着(这比kill -0 $pid更有效,因为即使你不拥有kill -0 $pid ,它也能工作)。

例如在GNU / Linux中,你可以使用:

 Pid=$(pidof `process_name`) if [ $Pid > 0 ]; then do something else do something fi 

或者类似的东西

 Pin=$(ps -A | grep name | awk 'print $4}') echo $PIN 

并显示您的应用程序的名称,只是没有ID的名称。

在这里我将PID存储在一个名为.pid的文件中(有点像/ run / …),只有在脚本没有执行的情况下才执行。

 #!/bin/bash if [ -f .pid ]; then read pid < .pid echo $pid ps -p $pid > /dev/null r=$? if [ $r -eq 0 ]; then echo "$pid is currently running, not executing $0 twice, exiting now..." exit 1 fi fi echo $$ > .pid # do things here rm .pid 

注意:有一个竞争条件,因为它不检查如何调用该PID。 如果系统重新启动并且.pid存在,但由另一个应用程序使用,则可能导致“无法预料的后果”。