shell 脚本中的 `kill -0 $pid` 有啥作用?

Posted

技术标签:

【中文标题】shell 脚本中的 `kill -0 $pid` 有啥作用?【英文标题】:What does `kill -0 $pid` in a shell script do?shell 脚本中的 `kill -0 $pid` 有什么作用? 【发布时间】:2012-06-16 06:31:36 【问题描述】:

基本上,'0'代表什么信号,因为here我看到的SIGNAL数字是从1开始的。

【问题讨论】:

linux.die.net/man/1/kill 另见Unix.SE variant of this question,它不同于 kill 0(无破折号),解释here和here。 【参考方案1】:

此命令检查 $pid 中具有 PID 的进程是否处于活动状态。

【讨论】:

手册页说:“如果 sig 为 0,则不发送信号,但仍会执行错误检查。”我们在这里指的是什么错误检查? -1,因为 PID $pid 的进程可能正在运行,但您无权向它发送信号。 @dwalter:如果您没有权限,您将获得 EPERM。如果它不存在,您将获得 ESRCH。 kill(1) 将为每个打印一个不同的错误。因此,无论您是否有权发送信号,您都可以判断 pid 是否处于活动状态。此外,kill -0 的典型用法是查看 pid 是否处于活动状态,即使它并不总是正确使用。我想说这个答案是正确的(除了拼写)。 @camh: 否kill -0 $pid 的返回值在两种情况下都相同。它将返回1,因此如果您无权向其发送信号,则如果进程是否正在运行,您不能不解析kill 的输出。编辑:是的,我知道它大部分时间用于检查进程是否处于活动状态,但这是错误的,除非您可以保证您有权发送信号(例如:作为 root) @dwalter:我的意思是答案是正确的。您试图迂腐并指出存在另一个错误案例,但我告诉您,从技术上讲,答案也涵盖了该案例,因为内置的kill bash(问题标记为bash)输出的类型为stderr 上的错误,并在其返回代码中指示错误。也就是说,如果您正确解释输出,“此命令检查 [是否] $pid 中具有 PID 的进程是否处于活动状态”是完全正确的。 [如果你没有说你给答案-1,我不会发表评论。您的评论在其他情况下有效]。【参考方案2】:

向给定的PID 发送信号0 只是检查是否有任何具有给定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.
...

【讨论】:

此信息的位置(如果存在的话)高度依赖于系统。在最近基于 Debian 的系统上,请改用 man 2 kill man 1 killman 2 kill 在我的 Fedora 20 系统上都有它。但是很难发现,埋在这两个手册页中。 或者改用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 我感觉man 2 kill这个命令在第一修正案之外:)【参考方案3】:

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

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

特别有用的信号包括 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) 这是 sn-p: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. 这应该是公认的答案。比另一个好很多。关于信号 0 的文档很难找到。它隐藏在kill 手册页中:“如果 sig 为 0,则不发送信号,但仍会执行错误检查。”【参考方案4】:

kill -0 $pid是检查进程id(pid)的进程是否存在。

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

    一旦预期的进程退出,它的 pid 就可以分配给其他新创建的进程。 (因此无法确定特定进程是否存在)

    在僵尸进程的情况下,哪个子进程正在等待父进程调用wait。在这里它保存 $pid 并在该进程未运行时给出肯定的结果。

【讨论】:

【参考方案5】:

kill -0 $pid 用于检查以$pid 运行的进程是否处于活动状态。但这可能很棘手,因为一旦进程退出并运行新进程,就可以重新分配进程 ID。

可以使用killall -0 <process name> 了解特定进程是否正在运行。

【讨论】:

【参考方案6】:

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

    检查进程是否存在。 对进程进行各种错误检查(PID、PGID 等...)。 成功后不会向stdout发送任何输出。 如果有问题,请向stderr 发送错误消息。 如果进程已失效(即僵尸),则给您一个误报。

更明确地说,对您的 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 $?

【讨论】:

以上是关于shell 脚本中的 `kill -0 $pid` 有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章

CentOS7 uwsgi重启(通过shell脚本获取进程号并kill)

shell 判断PID是不是存在,存在则kill掉,不存在则跳过

linux获取jmeter PID并且kill与启动

分享两个shell脚本关闭和启动

shell脚本判断是否存在某文件

linux 运行和停止jar的shell 脚本