如果进程告诉自己停止运行,Runit 将错误退出

Runit exits with error if process tells itself to go down

我看到 runit 出现一些意外行为,但不确定如何让它执行我想要的操作而不在终止期间抛出错误。我有一个进程,有时知道它应该停止自己而不是让自己重新启动(因此应该自己调用 sv d )。如果我从不更改用户,这会起作用,但如果我在 运行.

时切换到非根用户,则会产生错误

我将对两个示例使用相同的 finish 脚本:

#!/bin/bash -e
echo "downtest finished with exit code  and exit status "

按预期工作的 run 脚本(将 downtest finished with exit code 0 and exit status 0 打印到系统日志):

#!/bin/bash -e
exec 2>&1
echo "running downtest"
sv d downtest
exit 0

run 脚本未按预期运行(将 downtest finished with exit code -1 and exit status 15 打印到系统日志):

#!/bin/bash -e
exec 2>&1
echo "running downtest"
chpst -u ubuntu sudo sv d downtest
exit 0

如果我使用 su ubuntu 而不是 chpst,我会得到相同的结果。

关于为什么我会看到此行为以及如何修复它的任何想法,因此调用 sudo sv d downtest 会导致干净的进程退出而不是返回错误状态代码?

如果进程仍在 运行ning,

sv d 发送 SIGTERM。这是信号 15,因此将以相关方式处理错误。

相比之下,要告诉 运行ning 程序在其自行退出后不要再次启动(从而允许该机会),请改用 sv o (once) .

或者,您可以在需要时在脚本中捕获 SIGTERM:

trap 'exit 0' TERM

如果你想使这个成为条件:

trap 'if [[ $ignore_sigterm ]]; then exit 0; fi' TERM

...然后 运行

ignore_sigterm=1

触发前 sv d.

有一个解决方法尝试 运行 (chpst -u ubuntu sudo sv d downtest) 的子 shell 这将有助于允许调用最后一个 exit 0 因为现在没有被调用因为之前退出.

#!/bin/sh
exec 2>&1
echo "running downtest"
(sudo sv d downtest)
exit 0

确实,如果要停止或控制服务,您不需要 chpst -u ubuntu 来停止进程,因为另一个用户只需要调整对 ./supervise 目录的权限,这可能就是您的原因正在获取退出代码 -1

检查 runsv 人:

Two arguments are given to ./finish. The first one is ./run’s exit code, or -1 if ./run didn’t exit normally. The second one is the least significant byte of the exit status as determined by waitpid(2); for instance it is 0 if ./run exited normally, and the signal number if ./run was terminated by a signal. If runsv cannot start ./run for some reason, the exit code is 111 and the status is 0.

并且来自 faq


是否可以允许 root 以外的用户控制服务 使用 sv 程序控制服务,或查询其状态信息,只能以 root 身份使用。是否可以允许非 root 用户也控制服务?

答:可以,您只需要调整服务目录下./supervise/子目录的文件系统权限即可。例如:让用户burdon控制服务dhcp,切换到dhcp服务目录,做

# chmod 755 ./supervise
# chown burdon ./supervise/ok ./supervise/control ./supervise/status

如果你想完整 stop/start 你可以删除你的 run 服务的符号链接,但这意味着当你想要服务时重新创建它。

以防万一,因为这个和其他 cases, I came up with immortal to simplify the stop/start/restart/retries 没有 root 权限的服务,完全基于 daemontools & runit 只是适应一些新流程。