not*_*-jj 4 linux bash systemd
如何判断脚本是从 systemd 还是从用户调用的?
我为一个老式的守护进程创建了一个服务。我们刚刚切换到 systemd,我的一些管理员喜欢直接调用 rc-script。在机器重新启动的情况下,这不会很好地工作。Systemd 不会尊重 ,PIDFile=因为新启动的守护进程不是它的服务 cgroup 的一部分。
我添加了服务文件和 rc_script。我不能因用户 ID 而异,因为要使用脚本,用户必须是foobaruser.
停止服务现在有问题,因为 systemd 会从删除的 pid 文件中识别出这一点。
那么如何确定脚本是否是从 systemd 调用的呢?
[Unit]
Description=Foobar Service
After=syslog.target network.target
[Service]
Type=forking
User=foobaruser
LimitNOFILE=60000
LimitNPROC=8000
TasksMax=8000
PIDFile=/local/foobar/foo.pid
ExecStart=/opt/foobar/rc_script start
ExecStop=/opt/foobar/rc_script stop
TimeoutSec=100
TimeoutStopSec=300
KillMode=none
RemainAfterExit=no
Environment=LANG=de_DE.UTF-8
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
#!/bin/bash
case $1 in
start)
VAR_IS_SYSTEMD=$( ... script to check if bash is run from systemd ... )
if [ "$VAR_IS_SYSTEMD" = false ] ; then
sudo systemctl start foobar.service
exit
fi
# start service within systemd
;;
stop)
# stop service
;;
esac
Run Code Online (Sandbox Code Playgroud)
Luc*_*ter 11
我同意其他海报,您应该尝试重写服务以根本不调用脚本(如果您的管理员想继续使用它很好,但是 systemd 服务是否需要所有 36 个选项?) - 但它也不是很难检测脚本是否是从 systemd 调用的。
systemd v232 增加了单元的调用 ID 的概念,它在$INVOCATION_ID环境变量中传递给单元。您可以检查是否已设置。
systemd v231+$JOURNAL_STREAM为其 stdout 或 stderr 连接到日志的服务设置变量,这似乎适用于您的服务,因此如果您使用 systemd v231,您也可以检查该变量。(在 v232+ 上,$INVOCATION_ID绝对是更好的选择。)
在较旧的 systemd 版本上,我认为没有始终存在的环境变量,但您当然可以通过向您的服务中添加这样的内容来自己定义一个:
Environment=LAUNCHED_BY_SYSTEMD=1
Run Code Online (Sandbox Code Playgroud)一个简单的解决方案是使用不同的脚本来启动 systemd。/opt/foobar/rc_script 应该只调用systemctl start foobar.service和systemctl stop foobar.service。
Suse 使用$SYSTEMD_NO_WRAP,但我不知道这是 systemd 标准还是 Suse 特定的。
if test -z "$SYSTEMD_NO_WRAP"; then
...
/usr/bin/systemctl [start|stop] xxx.service
Run Code Online (Sandbox Code Playgroud)