Как использовать пробелы в аргументах командной строки systemd?

У меня есть systemd единица с пробелами в аргументе

ExecStart=command --argument="text text"

Кажется, что systemd не распознает двойные или одинарные кавычки и разбивает аргумент на два аргумента. Любая идея, как я могу это предотвратить? Я использую systemd v218 внутри CoreOS.

Ответ 1

Это, к сожалению, на самом деле удивительно сложно сделать. Я украл эту информацию из этого ответа. Единственный способ сделать это - поместить свои аргументы в файл окружения, а затем использовать их как переменные как таковые (например, в /etc/.progconfig):

ARG1=text
ARG2=text

Затем импортируйте файл окружения перед запуском вашей команды:

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

Ответ 2

systemd только, кажется, распознает кавычки, которые полностью переносят аргументы; то есть.

ExecStart=command "--argument=text text"

работает, но

ExecStart=command --argument="text text"

нет. Я просто столкнулся с этой проблемой и написал об этом # 624.

Ответ 3

Как предложил Нико, вы можете создать EvironmentFile, в котором вы можете указать аргумент с пробелами.

SPACEYARG="i love spaces"

Однако в вашем файле устройства вам необходимо обернуть этот аргумент в фигурные скобки, чтобы пробелы были правильно переданы.

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

Ответ 4

Я думаю, что последние версии systemd начали принимать кавычки в середине аргументов, ближе к тому, что принимает bash. Тем не менее, ответ @Tgr по-прежнему правилен, и стоит остановиться. Здесь указывается весь аргумент, включая имя флага. Если вы это сделаете:

ExecStart=command "--argument=text text"

Тогда systemd будет понимать --argument=text text как единственный позиционный аргумент. Вам не нужно беспокоиться о том, чтобы больше раскалываться на этом пространстве. Вы можете увидеть такое же поведение в bash:

$ echo "--silly-flag=spaces     are    preserved here"
--silly-flag=spaces     are    preserved here

Ответ 5

Сервисный файл 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"

Ответ 7

Попробуйте выполнить пробел, например:

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

(Кавычки могут быть или не быть необходимыми.)