如何在 systemd 命令行参数中使用空格?

How can I use spaces in systemd command line arguments?

我有一个在参数中有空格的 systemd 单元

ExecStart=command --argument="text text"

systemd 似乎不识别双引号或单引号,并将参数拆分为两个参数。知道如何防止这种情况吗?我在 CoreOS 中使用 systemd v218。

尝试转义 space,像这样:

ExecStart=command --argument="text\ text"

(引号可能需要也可能不需要。)

不幸的是,这实际上很难做到。我从 this answer 偷了这个信息。唯一的方法是将你的参数放在一个环境文件中,然后将它们用作变量(就像在 /etc/.progconfig 中):

ARG1=text
ARG2=text

然后在运行你的命令之前导入环境文件:

EnvironmentFile=/etc/.progconf
ExecStart = command $ARG1 $ARG2

systemd 似乎只能识别完全包含参数的引号;即

ExecStart=command "--argument=text text"

有效但

ExecStart=command --argument="text text"

没有。我只是 运行 关注这个问题并提交了 #624 关于它。

正如 Nico 所建议的,您可以创建一个 EvironmentFile,您可以在其中指定带空格的参数。

SPACEYARG="i love spaces"

但是,在您的单元文件中,您需要将该参数括在大括号中,以便正确传递空格。

EnvironmentFile=/etc/.progconf
ExecStart = command ${SPACEYARG}

我认为 systemd 的最新版本已经开始接受参数中间的引号,更接近于 bash 接受的内容。但是,@Tgr 的回答仍然是正确的,值得详细说明。引用整个参数,包括标志名称,在这里有效。如果你这样做:

ExecStart=command "--argument=text text"

然后 systemd 会将 --argument=text text 理解为单个位置参数。您不必担心 space 上会发生更多分裂。您可以在 bash:

中看到相同的行为
$ echo "--silly-flag=spaces     are    preserved here"
--silly-flag=spaces     are    preserved here

Systemd 服务文件支持这个

Environment="TEST=one word"
Environment="TEST2=second word"

ExecStartPre=-/bin/echo start pre
ExecStartPre=/bin/echo start pre mandatory
ExecStart=/bin/echo started : ${TEST} $TEST2
ExecStartPost=-/bin/echo start post
ExecStartPost=/bin/echo start post mandatory
ExecStop=/bin/echo stop
ExecStopPost=-/bin/echo stop post
ExecStopPost=/bin/echo stop post mandatory
ExecReload=/bin/echo reload

日志:

Mar 09 21:39:47 gitlab-runner-1 echo[30286]: start pre
Mar 09 21:39:47 gitlab-runner-1 echo[30288]: start pre mandatory
Mar 09 21:39:47 gitlab-runner-1 echo[30295]: started : one word second word
Mar 09 21:39:47 gitlab-runner-1 echo[30296]: start post
Mar 09 21:39:47 gitlab-runner-1 echo[30297]: start post mandatory
Mar 09 21:39:47 gitlab-runner-1 echo[30298]: stop
Mar 09 21:39:47 gitlab-runner-1 echo[30299]: stop post
Mar 09 21:39:47 gitlab-runner-1 echo[30300]: stop post mandatory

但如果应用需要将整个字符串作为 2 个参数读取,每个参数都在“”之间(未测试),您可能实际上想要设置此设置

ExecStart=command "$ARG1" "$ARG2"

环境是一种方式。

您也可以将 \s 用作 space,因此 ExecStart 将是:

ExecStart=command --argument="text=\stext"

参考:https://www.freedesktop.org/software/systemd/man/systemd.service.html#Command%20lines