Shell脚本中的`kill -0 $ pid`有什么作用?


Answers:


136

将信号发送0给给定对象PID只是检查给定对象PID是否正在运行任何进程,并且您有权向其发送信号。

有关更多信息,请参见以下联机帮助页:

杀死(1)
$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
杀死(2)
$ man 2 kill
...
If sig is 0, then no signal is sent, but error checking is still performed; this 
can be used to check for the existence of a process ID or process group ID.
...

7
此信息的位置(如果存在)完全取决于系统。在最近的基于Debian的系统上,请man 2 kill改用。
Todd A. Jacobs 2013年

2
双方man 1 killman 2 kill有它我的Fedora 20系统上。虽然很难发现,但它们都埋在这两个手册页中。
slm 2014年

或改为依靠posix手册:If sig is 0 (the null signal), error checking is performed but no signal is actually sent. The null signal can be used to check the validity of pid. pubs.opengroup.org/onlinepubs/009695399/functions/kill.html
Thomas Hughes,

2
我觉得命令man 2 kill不在第一修正案之内:)
JBaczuk

126

这是一个好问题,因为...

...可能很难找到有关此特殊信号的文档。不管别人怎么说,在man 1 kill基于Debian的系统中唯一提及此信号的是:

特别有用的信号包括HUP,INT,KILL,STOP,CONT和0。

没有特别的帮助,特别是如果您还不知道信号的作用。的输出也未列出它kill -l,因此除非您已经知道它,否则您将不会知道它。

在哪里找到记录

在Debian和Ubuntu系统上,输出的man 2 kill一部分表示:

如果sig为0,则不发送信号,但仍执行错误检查;这可用于检查是否存在进程ID或进程组ID。

有什么好处

您可以kill -0用来检查进程是否正在运行。考虑这些例子。

# Kill the process if it exists and accepts signals from
# the current user.
sleep 60 &
pid=$!
kill -0 $pid && kill $pid

# Check if a PID exists. When missing, this should result
# in output similar to:
#    bash: kill: (6228) - No such process
#    Exit status: 1
kill -0 $pid; echo "Exit status: $?"

您还可以kill -0用来确定当前用户是否具有发信号通知给定进程的权限。例如:

# See if you have permission to signal the process. If not,
# this should result in output similar to:
#     bash: kill: (15764) - Operation not permitted
#     Exit status: 1
sudo sleep 60 &
kill -0 $!; echo "Exit status: $?"

在Mac和BSD上,它也记录在kill(2) 以下代码段中:The kill() function sends the signal specified by sig to pid, a process or a group of processes. Typically, Sig will be one of the signals specified in sigaction(2). A value of 0, however, will cause error checking to be performed (with no signal being sent). This can be used to check the validity of pid.
lukecampbell,2014年

8
这应该是公认的答案。比另一个更好。信号0上的文档很难找到。它埋在kill手册页中:“如果sig为0,则不发送信号,但仍执行错误检查。”
slm 2014年

6

该命令检查$ pid中带有PID的进程是否有效。


1
手册页说:“如果sig为0,则不发送信号,但仍执行错误检查。” 我们在这里指的是什么错误检查?
gjain 2012年

2
-1,因为带有PID的进程$pid可能正在运行,但您无权向其发送信号。
dwalter 2012年

2
@dwalter:如果没有权限,您将获得一个EPERM。如果不存在,您将获得一个ESRCH。在kill(1)将打印不同的错误每个。因此,无论您是否具有发送信号的权限,您都可以确定该pid是否仍然存在。此外,的典型用法kill -0是查看pid是否仍处于活动状态,即使它并非总是正确使用也是如此。我会说这个答案是正确的(除了拼写)。
卡姆

3
@camh:kill -0 $pid在两种情况下,no的返回值都不会相同。它会返回,1因此如果您没有解析该kill进程是否正在运行的输出,或者您没有向该进程发送信号的权限,则无法不说。编辑:是的,我知道大多数时候都使用它来检查进程是否处于活动状态,但这是错误的,除非您可以保证您具有发送信号的权限(例如:被root用户)
dwalter 2012年

2
@dwalter:我的意思是答案是正确的。您尝试过学究,并指出还有另一种错误情况,但是我告诉您,从技术上讲,答案也涵盖了这种情况,因为kill内置的bash(标记了问题bash)会在stderr上输出错误的类型,并指示返回代码中的错误。也就是说,如果正确解释了输出,则“此命令将检查[pid] $ pid中的PID进程是否有效”。[如果您不说回答-1,我不会发表评论。您的评论否则有效]。
camh 2012年

6

Kill -0 $ pid用于检查带有pid的进程是否存在。

使用'kill -0 $ pid'检查进程存在时要小心,因为

  1. 一旦预期的进程退出,则可以将其pid分配给其他新创建的进程。(因此,不能肯定特定进程是否存在)

  2. 在僵尸进程的情况下,哪个孩子正在等待父级呼叫等待。在这里,它持有$ pid并在该进程未运行时给出正结果。


1

Kill -0 $ pid用于检查使用$ pid运行的进程是否活动。但这很棘手,因为一旦进程退出并运行新进程,就可以重新分配进程ID。可以使用killall -0来了解某个特定进程是否正在运行。


0

发送EXIT信号或发送0到进程将:

  1. 检查是否存在进程。
  2. 对进程进行各种错误检查(PID,PGID等)。
  3. stdout成功时不会发送任何输出。
  4. stderr如果出现错误,请发送错误消息给。
  5. 如果该过程已终止(例如Zombie),则给您误报。

更明确地说,对于您的shell脚本有用的功能是:

function isProcess ()
{
    kill -s EXIT $1 2> /dev/null
}

stdout成功时不会返回任何文本,但stderr失败时会返回错误消息(但我已将该错误消息重定向到/dev/null)。

如果您担心失效/僵尸进程状态,则需要使用ps,最好与--no-headers开关一起使用。

#!/bin/ksh

function trim ()
{
    echo -n "$1" | tr -d [:space:]
}

function getProcessStatus ()
{
    trim $(ps -p $1 -o stat --no-headers)
}

function isZombie ()
{
    typeset processStatus=$(getProcessStatus $1)

    [[ "$processStatus" == "Z" ]]
    return $?
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.