如何调试systemd单元ExecStart

pys*_*ole 19 systemd

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

ExecStart=/usr/bin/java $OPTS_COMMON $OPTS $OPTS_LOG $OPTS_DEBUG some.class.Start --param1 ${PARAM1} --param2 ${PARAM2}
Run Code Online (Sandbox Code Playgroud)

我有很长的命令行,其中涉及很多环境变量。如果某些变量出错(例如通过直接配置),服务可能根本无法启动。但是,我在任何地方都没有看到完全扩展的带有替换环境的行,我很难找出问题所在。

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

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

小智 19

不幸的是,没有内置的方法。要查看最终的 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(说明符)

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

  • 我发现上面提到的“LogLevel=debug”确实有效,但直到我运行此命令来重新加载 systemd 管理器配置。:“systemctl daemon-reload”。 (3认同)

U. *_*ndl 5

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

像这样:

ExecStart=/path/to/wrapper /usr/bin/java $OPTS_COMMON $OPTS $OPTS_LOG $OPTS_DEBUG some.class.Start --param1 ${PARAM1} --param2 ${PARAM2}
Run Code Online (Sandbox Code Playgroud)

包装脚本本身可以是:

#!/bin/sh
LOGFILE=/some/safe/file
for param
do
    echo "param: $param"
done > $LOGFILE
exec "$@"
Run Code Online (Sandbox Code Playgroud)