在bash脚本中,我想做以下事情(在伪代码中):

if [ a process exists with $PID ]; then

    kill $PID 

fi

条件语句的合适表达式是什么?


当前回答

要检查进程是否存在,请使用

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

其他回答

最好的方法是:

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 $known_running_pid

and

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文件怎么办?

看起来你想要

wait $PID

当$pid结束时返回。

否则你可以使用

ps -p $PID

检查进程是否仍然活跃(这比kill -0 $pid更有效,因为即使你不拥有pid,它也会工作)。

在这里,我将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存在,但被不同的应用程序使用,这可能会导致“不可预见的后果”。

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

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

例如,在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。