在Bash脚本中,我想要执行以下操作(伪代码):
if [ a process exists with $PID ]; then
kill $PID
fi
条件语句的适当表达式是什么?
在Bash脚本中,我想要执行以下操作(伪代码):
if [ a process exists with $PID ]; then
kill $PID
fi
条件语句的适当表达式是什么?
最好的方式是:
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
的问题在于,即使进程正在运行且您没有权限将其终止,退出代码也将为非零。例如:
问题在于 kill -0 $PID
命令不论进程是否正在运行,都会返回0作为成功的退出代码。因此,如果您要确保进程正在运行并且您有权限终止它,则应使用不同的方法。
kill -0 $known_running_pid
和
kill -0 $non_running_pid
有非零的退出代码,对于普通用户来说无法区分,但其中一个假设在运行,而另一个则没有。
部分相关的信息,由AnrDaemon提供:init进程(PID 1)肯定在所有Linux机器上运行,但不是所有POSIX系统都是Linux。在那里不能保证存在PID 1:
kill -0 1
-bash: kill: (1) - No such process …
如果测试主体是“终止”,那么讨论杀死和竞态条件的答案是完全正确的。我是来寻找关于如何在bash中测试PID存在性的一般性问题的。
/proc
方法很有趣,但在某种程度上打破了 ps
命令的抽象层次,也就是说,您不需要查看 /proc
,因为如果Linus决定将 exe
文件改名,该方法可能会出现问题。
ps -p
命令没有匹配到任何正在运行的进程时,它会打印一个空的进程列表并返回状态码 0。请注意,这里的翻译并未改变原意,只是将其转化为更易懂的中文表达方式。 - Douglas Correatest -d /proc/$PID
而不是启动其他进程。请注意,您永远无法知道某个进程是否存在于另一个PID名称空间中。 - Mikko Rantalainen要检查进程是否存在,请使用
kill -0 $pid
但就像@unwind所说的那样,如果你想让程序在所有情况下都终止,那么只需要
kill $pid
否则你会出现竞态条件,进程在第一个kill -0
后可能已经消失。kill
的文本输出并根据退出代码执行某些操作,则可以...if ! kill $pid > /dev/null 2>&1; then
echo "Could not send SIGTERM to process $pid" >&2
fi
kill -0
命令,实际上需要执行以下操作:kill -0 25667; echo $?
- 然后如果返回值是0
,则表示可以杀死该PID的进程;如果该进程PID(例如)不存在,则$?
将为1
,表示失败。这样正确吗? - sdaauif ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
。 - Will$PID
为空,则[ -e /proc/$PID ]
仍将返回true,因为/proc/
目录仍然存在。 - Magne-e /proc/$PID/status
使 -n "$PID"
检查变得不必要,因为没有 /proc//status
文件。 - Maxim Egorushkinps
命令加上 -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
有什么问题吗?
编辑:
经过大约24个月的思考...原来我给出的想法很巧妙,但是高度不可移植。虽然它教授了Linux的一些实现细节,但它在Mac、Solaris或*BSD上将无法工作。甚至可能在未来的Linux内核上失败。请使用其他答案中描述的“ps”。
/proc/$PID/exe
不是一个普通的文件。因此,[ -f /proc/$PID/exe ]
将始终返回 false
结果。请尝试 [ -h /proc/$PID/exe ]
。 - Alexander Yancharuk看起来你想要
wait $PID
当$pid
完成时,将返回结果。
否则,您可以使用
ps -p $PID
检查进程是否仍在运行(这比kill -0 $pid
更有效,因为即使您不拥有pid,它也可以工作)。
我认为那是一个不好的解决方案,会导致竞态条件。如果进程在你的测试和kill调用之间死亡了,那么kill将失败。所以为什么不在所有情况下尝试kill,并检查其返回值以了解情况如何呢?
kill -9
命令,它会立即杀死进程,并不给予进程清理自身的机会。相反,应该使用 kill
命令,它等效于 kill -15
命令。如果这不能解决问题,你应该找出原因,并只在万不得已时使用 kill -9
命令。 - Christoffer HammarströmPid=$(pidof `process_name`)
if [ $Pid > 0 ]; then
do something
else
do something
fi
Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN
这将显示应用程序的名称,仅名称而不包括ID。
pidof
does not return a negative number, as a negative PID does not make any sense, and you can't kill init
, so your conditional makes no sense (and besides, you'd need to escape the >
to prevent it from performing a redirection). You want to check for an empty result, but of course, like any decent tool, pidof
sets an exit code to tell you whether it worked, so the proper solution is if Pid=$(pidof 'process_name'); then ...
or (if you won't need the value in Pid
later on) simply if pidof 'process_name'; then...
- tripleeepidof
的例子充满了对 bash test
工作方式的误解。https://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html - Bruno Bronosky由pid:
pgrep [pid] >/dev/null
由名称:
pgrep -u [user] -x [name] >/dev/null
我将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存在但被不同应用程序使用,则可能会导致“意想不到的后果”。