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 kill
和 man 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)