slm*_*slm 84 shell process kill
我最近在 shell 脚本中遇到了这个问题。
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
Run Code Online (Sandbox Code Playgroud)
有什么作用kill -0 ...?
slm*_*slm 101
这个有点难以收集,但如果您查看以下 2 个手册页,您将看到以下注释:
杀死(1)$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
Run Code Online (Sandbox Code Playgroud)
杀死(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.
...
Run Code Online (Sandbox Code Playgroud)
因此,信号 0 实际上不会向您的进程的 PID 发送任何内容,但会检查您是否有权这样做。
一个明显的地方是,如果您试图确定您是否有权通过kill. 您可以在发送kill您想要的实际信号之前进行检查,通过包装检查以确保kill -0 <PID>首先允许。
假设一个进程由 root 运行,如下所示:
$ sudo sleep 2500 &
[1] 15693
Run Code Online (Sandbox Code Playgroud)
现在在另一个窗口中,如果我们运行此命令,我们可以确认该 PID 正在运行。
$ pgrep sleep
15693
Run Code Online (Sandbox Code Playgroud)
现在让我们试试这个命令,看看我们是否可以通过kill.
$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!
Run Code Online (Sandbox Code Playgroud)
所以它有效,但输出从kill我们没有权限的命令中泄漏了一条消息。没什么大不了的,只需捕获 STDERR 并将其发送到/dev/null.
$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!
Run Code Online (Sandbox Code Playgroud)
那么我们可以做这样的事情,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
Run Code Online (Sandbox Code Playgroud)
现在,当我以非 root 用户身份运行上述内容时:
$ ~/killer.bash
you don't have permissions to kill PID:15693
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)
但是,当它以 root 身份运行时:
$ sudo ~/killer.bash
$ echo $?
0
$ pgrep sleep
$
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 28
kill -0(或其更便携的 POSIX 变体kill -s 0)经历了发送信号的过程,但实际上并不发送信号。这是一个特点底层C API的shell命令以简单的方式曝光。
kill -s 0 -- "$pid"因此测试是否存在具有给定 PID(或 PGID,如果$pid为负)的正在运行的进程,以及当前进程是否有权向它(进程组中的任何进程,如果为负$pid)发送信号。它主要是一种测试进程(或进程组)是否存活的方法。
请记住,即使存在具有预期 PID 和权限的正在运行的进程,这也不一定是您期望的进程。您期望的进程可能更早死亡,并且其 PID 被重用于不相关的进程。监控进程的正确方法是让它们的父进程来做——一个进程的 PID 不会被重用,直到它的父进程确认它的死亡(这就是僵尸存在的原因),所以一个进程的父进程可以通过它们的 PID 可靠地识别它的子进程。