如何调试 systemd unit ExecStart

如何调试 systemd unit ExecStart

我很好奇我是否可以打印出完全展开的ExecStart/ExecStop命令行。请考虑以下示例:

ExecStart=/usr/bin/java $OPTS_COMMON $OPTS $OPTS_LOG $OPTS_DEBUG some.class.Start --param1 ${PARAM1} --param2 ${PARAM2}

我的命令行很长,包含很多环境变量。如果某些变量出错(例如,由于插入配置),服务可能根本无法启动。但是,我没有在任何地方看到完全展开的行和替换的环境,我很难找出问题所在。

我在谷歌上搜索这个问题,但没找到任何线索,到目前为止,我发现的唯一可能性是修改要运行的单元文件,/usr/bin/echo而不是修改服务本身。但这有点累人。或者更烦人的解决方案——逐一检查每个环境变量。

有没有什么方法可以强制 systemd 显示实际尝试运行的内容?

答案1

不幸的是,没有内置的方法。要查看最终的 ExecStart,您可以打开调试。编辑文件/etc/systemd/system.conf并将 设置为LogLevel=debug然后您将看到类似以下内容:

java.service About to execute: /usr/bin/java $OPTS_COMMON...这并不能解决您的问题,但是看到 systemd 的说明符替换还是不错的。https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Specifiers

但如果您真的想彻底了解参数替换,您需要查看这里:https://github.com/systemd/systemd/blob/7ce9cc154576e342015eab8c1500790a9ededc01/src/core/execute.c#L2570


答案2

不要使用命令行来执行,而是使用具有相同命令和参数的包装脚本(或二进制文件)。然后包装脚本记录参数,然后执行真正的命令。

像这样:

ExecStart=/path/to/wrapper /usr/bin/java $OPTS_COMMON $OPTS $OPTS_LOG $OPTS_DEBUG some.class.Start --param1 ${PARAM1} --param2 ${PARAM2}

包装脚本本身可以是:

#!/bin/sh
LOGFILE=/some/safe/file
for param
do
    echo "param: $param"
done > $LOGFILE
exec "$@"

答案3

在 *.service 文件的 [Service] 部分中

ExecStartPre=/bin/bash -l -c 'echo "$OPTS_COMMON">/tmp/options.debug'

相关内容