如何指定包含 = 的环境 systemd 指令?

如何指定包含 = 的环境 systemd 指令?

我想指定一个Environment systemd包含的指令=,例如

Environment=CATALINA_OPTS=-Dappserver.home=/var/lib/archiva/apache-tomcat-current -Dappserver.base=/var/lib/archiva/apache-tomcat-current

并得到错误

[/lib/systemd/system/archiva.service:10] Invalid environment assignment, ignoring: CATALINA_OPTS=-Dappserver.home\=/var/lib/archiva/apache

在 中journalctl -xe。我尝试使用 和 进行引用,"'使用 进行转义=,但\没有成功。这似乎没有记录。

答案1

我认为您的问题是由于环境变量内容中的空格造成的。查看以下示例systemd 文档,赋值应该是一个字符串:

例子:

Environment="ONE=one" 'TWO=two two'
ExecStart=/bin/echo $ONE $TWO ${TWO}

这将使用四个参数执行 /bin/echo:onetwotwotwo two

例子:

Environment=ONE='one' "TWO='two two' too" THREE=
ExecStart=/bin/echo ${ONE} ${TWO} ${THREE}
ExecStart=/bin/echo $ONE $TWO $THREE

这导致 echo 被调用两次,第一次使用参数 'one', 'two two' too, ,第二次使用参数 one, two two, too

我使用以下服务对此进行了测试(请注意整个作业周围的引号):

[Unit]
Description=My Daemon

[Service]
Environment='CATALINA_OPTS=-Dappserver.home=/var/lib/archiva/apache-tomcat-current -Dappserver.base=/var/lib/archiva/apache-tomcat-current'
ExecStart=/bin/echo ${CATALINA_OPTS}

[Install]
WantedBy=multi-user.target

并得到所需的输出journalctl

Apr 26 08:19:29 laptop echo[28439]: -Dappserver.home=/var/lib/archiva/apache-tomcat-current -Dappserver.base=/var/lib/archiva/apache-tomcat-current

当然,使用它更简单EnvironmentFileEnvironment用以下内容替换可以得到相同的结果:

EnvironmentFile=/tmp/foo

包含内容/tmp/foo(请注意没有引号):

CATALINA_OPTS=-Dappserver.home=/var/lib/archiva/apache-tomcat-current -Dappserver.base=/var/lib/archiva/apache-tomcat-current

答案2

除了接受的答案所说的内容之外,如果将环境变量放入插入文件中,则需要使用以下语法来确保它们不会全部被视为程序的一个参数:

环境配置文件插入文件

[Service]
Environment='CATALINA_OPTS=-Dappserver.home=/var/lib/archiva/apache-tomcat-current -Dappserver.base=/var/lib/archiva/apache-tomcat-current'

单位服务

[Unit]
Description=My Daemon

[Service]
ExecStart=/bin/echo $CATALINA_OPTS

[Install]
WantedBy=multi-user.target

我不知道为什么 using$ENV_NAME对我有用,而${ENV_NAME}对我没用,而且我找不到任何记录这种差异的东西。我只能说$ENV_NAME语法可以将变量中由空格分隔的每个参数视为不同的参数,而${ENV_NAME}, 将它们全部视为一个参数。

也许使用echo不是区分这种差异的最佳方式。我建议任何想要测试它的人使用类似/usr/bin/printf "%s\n" ${ENV_NAME}vs 的东西/usr/bin/printf "%s\n" $ENV_NAME,看看他们会得到什么。

创建插入文件

可以使用 systemctl 命令创建一个插入文件edit。例如,在本问题中,命令将是:

sudo systemctl edit archiva.service

您也可以像我上面所做的那样,通过将自定义文件添加到/lib/systemd/system/archiva.service.d/文件夹来创建一个


编辑

我发现文档观察到的环境变量行为,得益于另一个回答

支持基本的环境变量替换。在命令行中,将“${FOO}”用作单词的一部分或作为其本身的一个单词,在这种情况下,它将被删除并替换为环境变量的准确值(如果有),包括它包含的所有空格,始终产生一个参数。在命令行中,将“$FOO”用作单独的单词,在这种情况下,它将被替换为在空格处拆分的环境变量的值,产生零个或多个参数。对于这种类型的扩展,拆分成单词时会考虑引号,之后会将其删除。

答案3

替代解决方案

“命令行和环境变量支持 C 转义”

  • “\n”换行符
  • “\r” 回车
  • “\t”标签
  • “\v”垂直制表符
  • “\”反斜杠
  • """ 双引号
  • “'”单引号
  • “\s” 空格
  • “\xxx”十六进制编码的字符数xx
  • “\nnn” 八进制编码中的字符数 nnn

https://www.freedesktop.org/software/systemd/man/systemd.service.html

相关内容