我最近在shell脚本中遇到了这个问题。
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
怎么kill -0 ...
办?
kill -0 $pid
在shell脚本呢?以及杀死0实际上是做什么的?。
我最近在shell脚本中遇到了这个问题。
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
怎么kill -0 ...
办?
kill -0 $pid
在shell脚本呢?以及杀死0实际上是做什么的?。
Answers:
收集起来有些困难,但是如果您查看以下2个手册页,则会看到以下注释:
杀死(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.
...
因此,信号0实际上实际上不会向您的进程的PID发送任何信息,但会检查您是否具有这样做的权限。
一个明显的地方是您是否要尝试确定是否有权通过来向正在运行的进程发送信号kill
。您可以在发送所需的实际kill
信号之前进行检查,方法是包装检查以确保kill -0 <PID>
首先允许该信号。
假设某个进程正在由root用户运行,如下所示:
$ sudo sleep 2500 &
[1] 15693
现在在另一个窗口中,如果我们运行此命令,我们可以确认PID正在运行。
$ pgrep sleep
15693
现在,让我们尝试使用此命令,看看是否可以通过发送该PID信号kill
。
$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!
这样就可以了,但是输出泄漏了来自kill
我们没有权限的命令的消息。没什么大不了的,只需捕获STDERR并将其发送给/dev/null
。
$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!
因此,我们可以执行以下操作killer.bash
:
#!/bin/bash
PID=$(pgrep sleep)
if ! kill -0 $PID 2>/dev/null; then
echo "you don't have permissions to kill PID:$PID"
exit 1
fi
kill -9 $PID
现在,当我以非root用户身份运行以上命令时:
$ ~/killer.bash
you don't have permissions to kill PID:15693
$ echo $?
1
但是,当它以root身份运行时:
$ sudo ~/killer.bash
$ echo $?
0
$ pgrep sleep
$
pgrep
,ps
解析或test -e /proc/$PID
在便携式便笺中使用,但kill -0
可以在任何地方使用。如果给您的PID可能是陈旧的(例如,/var/run
条目),则这是检查过程是否仍然有效的便携式方法。
kill -0 $(pgrep sleep)
不一定意味着您很虚弱,如果没有sleep
命令在运行,或者有多个命令无法杀死,或者其中一个睡眠在pgrep和kill之间死掉,则失败将返回false。命令正在运行。
kill -0
(或更便携的POSIX变体kill -s 0
)通过发送信号的过程进行操作,但实际上并未发送信号。这是一个功能基础C API的shell命令以简单的方式公开。
kill -s 0 -- "$pid"
因此,测试是否存在具有给定PID(如果$pid
为负,则为PGID )的正在运行的进程,以及当前进程是否有权发送该信号(如果为负,则为进程组中的任何进程$pid
)。它主要是测试流程(或流程组)是否存在的一种方法。
请记住,即使正在运行的进程具有预期的PID和权限,也不一定是您期望的进程。您期望的进程可能会更早死亡,并且其PID会被重新用于无关的进程。监视进程的正确方法是让其父进程执行-进程的PID在父进程确认其死亡之前不会重复使用(这就是存在僵尸的原因),因此进程的父进程可以通过其PID可靠地标识其子进程。
该kill -0 $pid
如果一个进程有告诉你$pid
的存在。
在摘要中
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
... do something ...
如果/path/to/file.pid
正在运行带有存储PID的进程,则执行该块;并且-除非代码段以root身份运行,否则-如果该PID在同一用户下运行。
POSIX标准指定了0
信号的作用:
如果sig为0(空信号),则执行错误检查,但实际上未发送任何信号。空信号可用于检查pid的有效性。
(kill(3p),POSIX.1-2008-POSIX.1-2001中的类似措辞)
需要注意的是POSIX同时指定kill -0
和kill -s 0
命令行方式(杀死(1P))。
与kill syscall接口相反,该kill
命令不能用于可靠地检查其他用户(作为普通用户)拥有的PID的存在,例如:
$ kill -0 123
kill: kill 123 failed: no such process
$ echo $?
1
与
$ kill -0 1
kill: kill 1 failed: operation not permitted
$ echo $?
1
当调用kill syscall时,可以通过查看该errno
值来可靠地区分这些情况(例如,参见Python Example)。
trap
命令与0与信号0之间的差异感到困惑,请参阅此处kill
:陷阱命令中的信号0是什么?