3

我看到 runit 出现一些意外行为,不知道如何让它做我想做的事情,而不会在终止期间引发错误。我有一个进程有时知道它应该停止自己而不是让自己重新启动(因此应该sv d自己调用)。如果我从不更改用户,但如果我在运行时切换到非 root 用户会产生错误,则此方法有效。

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

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

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导致干净的进程退出而不是返回错误状态代码?

4

2 回答 2

2

sv d如果进程仍在运行,则发送 SIGTERM。这是信号 15,因此错误是以所讨论的方式处理的。

相反,要告诉正在运行的程序在它自己退出后不要再次启动(从而允许这个机会),请改用sv o( once) 。

或者,您可以在您期望的时候在脚本中捕获 SIGTERM:

trap 'exit 0' TERM

如果你想让这个有条件:

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

...然后运行

ignore_sigterm=1

在触发之前sv d

于 2018-07-27T19:42:22.930 回答
1

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

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

实际上,chpst -u ubuntu如果要停止或控制服务,因为另一个用户只需要调整对./supervise目录的权限,就不需要停止进程,这就是为什么您可能会得到退出代码 -1

检查runsv男人:

./finish 有两个参数。第一个是 ./run 的退出代码,如果 ./run 没有正常退出,则为 -1。第二个是由 waitpid(2) 确定的退出状态的最低有效字节;例如,如果 ./run 正常退出,则为 0,如果 ./run 被信号终止,则为信号编号。如果runsv由于某种原因无法启动./run,则退出码为111,状态为0。

常见问题解答


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

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

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

如果您想完全停止/启动,您可以删除run服务的符号链接,但这意味着当您希望服务启动时再次创建它。

以防万一,因为这个和其他情况,我想出了immortal来简化没有 root 权限的服务的停止/启动/重新启动/重试,完全基于 daemontools & runit 刚刚适应了一些新的流程。

于 2018-07-29T07:53:24.607 回答