在bash脚本中,我想执行以下操作(使用伪代码):
if [ a process exists with $PID ]; then
kill $PID
fi
条件语句的适当表达式是什么?
答案 0 :(得分:225)
最好的方法是:
if ps -p $PID > /dev/null
then
echo "$PID is running"
# Do something knowing the pid exists, i.e. the process with $PID is running
fi
问题:
kill -0 $PID
即使pid正在运行并且你没有权限杀死它,退出代码也将为非零。例如:
kill -0 1
和
kill -0 $non-running-pid
普通用户有一个难以区分的(非零)退出代码,但init进程(PID 1)肯定在运行。
如果测试的主体是“杀戮”,那么讨论杀人和竞争条件的答案是完全正确的。我来找一般的“你如何测试bash中的PID存在”。
/ proc方法很有意思,但在某种意义上打破了“ps”命令抽象的精神,即你不需要去查看/ proc,因为如果Linus决定调用“exe”文件是什么呢?
答案 1 :(得分:161)
要检查进程是否存在,请使用
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
答案 2 :(得分:57)
if [ -n "$PID" -a -e /proc/$PID ]; then
echo "process exists"
fi
或
if [ -n "$(ps -p $PID -o pid=)" ]
在后一种形式中,-o pid=
是一种输出格式,仅显示没有标题的进程ID列。对于非空字符串运算符-n
,引号为necessary以提供有效结果。
答案 3 :(得分:31)
ps
的 -p $PID
命令可以执行此操作:
$ ps -p 3531
PID TTY TIME CMD
3531 ? 00:03:07 emacs
答案 4 :(得分:10)
您有两种方式:
让我们首先在笔记本电脑中寻找特定的应用程序:
[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 for 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
BTW:kill -9 $PID || true
出了什么问题?
编辑:
在考虑了几个月之后..(大约24 ...)我在这里给出的最初想法是一个很好的黑客,但非常不可移植。虽然它教授了Linux的一些实现细节,但它无法在Mac,Solaris或* BSD上运行。它甚至可能在未来的Linux内核上失败。请 - 使用“ps”,如其他回复中所述。
答案 5 :(得分:7)
我认为这是一个糟糕的解决方案,可以满足竞争条件。如果这个过程在你的测试和你的杀戮之间死亡怎么办?然后杀死将失败。那么为什么不在所有情况下尝试杀死,并检查其返回值以找出它是如何进行的?
答案 6 :(得分:3)
好像你想要
wait $PID
将在$pid
完成时返回。
否则你可以使用
ps -p $PID
检查进程是否仍然有效(这比kill -0 $pid
更有效,因为即使您不拥有pid,它也会有效。)
答案 7 :(得分:1)
通过pid:
pgrep [pid] >/dev/null
按名称:
pgrep -u [user] -x [name] >/dev/null
“-x”表示“完全匹配”。
答案 8 :(得分:0)
例如,在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的名称。
答案 9 :(得分:0)
这里我将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存在但被其他应用程序使用,则可能会导致“不可预见的后果”。
答案 10 :(得分:0)
下面的代码检查我的进程是否正在运行,如果不执行任何操作。
仅在流程未运行时,才每小时检查一次来自Amazon SQS的新消息。
#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
/usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
echo "do nothing, just smile =)"
fi
exit $?