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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3043978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:21:49  来源:igfitidea点击:

How to check if a process id (PID) exists

bashprocesspid

提问by Richard H

In a bash script, I want to do the following (in pseudo-code):

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

if [ a process exists with $PID ]; then

    kill $PID 

fi

What's the appropriate expression for the conditional statement?

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

采纳答案by Christoffer Hammarstr?m

To check for the existence of a process, use

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

kill -0 $pid

But just as @unwind said, if you're going to kill it anyway, just

但正如@unwind 所说,如果你无论如何要杀死它,就

kill $pid

or you will have a race condition.

否则你会遇到竞争条件。

If you want to ignore the text output of killand do something based on the exit code, you can

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

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

回答by FDS

The best way is:

最好的办法是:

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

The problem with:

问题在于:

kill -0 $PID

is the exit code will be non-zero even if the pid is running and you dont have permission to kill it. For example:

即使pid正在运行并且您无权杀死它,退出代码也将是非零的。例如:

kill -0 1

and

kill -0 $non-running-pid

have an indistinguishable (non-zero) exit code for a normal user, but the init process (PID 1) is certainly running.

对于普通用户,有一个无法区分的(非零)退出代码,但 init 进程(PID 1)肯定正在运行。

DISCUSSION

讨论

The answers discussing kill and race conditions are exactly right if the body of the test is a "kill". I came looking for the general "how do you test for a PID existence in bash".

如果测试的主体是“kill”,那么讨论 kill 和 Race conditions 的答案是完全正确的。我来寻找一般的“你如何测试 bash 中的 PID 存在”。

The /proc method is interesting, but in some sense breaks the spirit of the "ps" command abstraction, i.e. you dont need to go looking in /proc because what if Linus decides to call the "exe" file something else?

/proc 方法很有趣,但从某种意义上说,它打破了“ps”命令抽象的精神,也就是说,您不需要去查看 /proc,因为如果 Linus 决定将“exe”文件称为别的东西怎么办?

回答by user2683246

if [ -n "$PID" -a -e /proc/$PID ]; then
    echo "process exists"
fi

or

或者

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

In the latter form, -o pid=is an output format to display only the process ID column with no header. The quotes are necessaryfor non-empty string operator -nto give valid result.

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

回答by oherrala

pscommand with -p $PIDcan do this:

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

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

回答by elcuco

You have two ways:

你有两种方法:

Lets start by looking for a specific application in my laptop:

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

[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

All examples now will look for PID 3358.

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

First way: Run "ps aux" and grep for the PID in the second column. In this example I look for firefox, and then for it's PID:

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

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

So your code will be:

所以你的代码将是:

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

Second way: Just look for something in the /proc/$PIDdirectory. I am using "exe" in this example, but you can use anything else.

第二种方式:只需在/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

So your code will be:

所以你的代码将是:

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

BTW: whats wrong with kill -9 $PID || true?

BTW:kill -9 $PID || true怎么了?



EDIT:

编辑:

After thinking about it for a few months.. (about 24...) the original idea I gave here is a nice hack, but highly unportable. While it teaches a few implementation details of Linux, it will fail to work on Mac, Solaris or *BSD. It may even fail on future Linux kernels. Please - use "ps" as described in other responses.

经过几个月的思考......(大约24......)我在这里给出的最初想法是一个很好的黑客,但非常不可移植。虽然它讲授了 Linux 的一些实现细节,但它无法在 Mac、Solaris 或 *BSD 上运行。它甚至可能在未来的 Linux 内核上失败。请 - 使用“ps”,如其他回复中所述。

回答by Gagan Gami

It seems like you want

好像你想要

wait $PID

which will return when $pidfinishes.

$pid完成后将返回。

Otherwise you can use

否则你可以使用

ps -p $PID

to check if the process is still alive (this is more effective than kill -0 $pidbecause it will work even if you don't own the pid).

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

回答by unwind

I think that is a bad solution, that opens up for race conditions. What if the process dies between your test and your call to kill? Then kill will fail. So why not just try the kill in all cases, and check its return value to find out how it went?

我认为这是一个糟糕的解决方案,它为竞争条件开辟了道路。如果进程在您的测试和您的 kill 调用之间终止了怎么办?那么kill就会失败。那么为什么不在所有情况下都尝试 kill 并检查其返回值以了解它是如何进行的呢?

回答by inukaze

For example in GNU/Linux you can use:

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

Pid=$(pidof `process_name`)

if [ $Pid > 0 ]; then

   do something
else

   do something
fi 

Or something like

或者类似的东西

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

and that shows you the name of the app, just the name without ID.

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

回答by invalidmagic

here i store the PID in a file called .pid (which is kind of like /run/...) and only execute the script if not already being executed.

在这里,我将 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 
#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print }')
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 $?
twice, exiting now..." exit 1 fi fi echo $$ > .pid # do things here rm .pid

note:there is a race condition as it does not check how that pid is called. if the system is rebooted and .pid exists but is used by a different application this might lead 'unforeseen consequences'.

注意:存在竞争条件,因为它不检查该 pid 的调用方式。如果系统重新启动并且 .pid 存在但被不同的应用程序使用,这可能会导致“不可预见的后果”。

回答by Brian Sanchez

code below checks if my process is running, if so do nothing.

下面的代码检查我的进程是否正在运行,如果正在运行,则不执行任何操作。

let's check new messages from Amazon SQS every hour only and only if the process is not running.

让我们每小时检查一次来自 Amazon SQS 的新消息,并且仅在进程未运行时检查。

##代码##