Расширение Bash Brace в Systemd ExecStart

Следующий тест в CentOS 7.1.

Создайте следующий файл test.service в /usr/lib/systemd/system/

[Unit]
Description=Test Bash Brace Expansion
Wants=network.target
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c "a='hello world'; echo ${a}"

[Install]
WantedBy=multi-user.target

и выполнить systemctl daemon-reload; systemctl restart test; systemctl status test -l

Нет выхода значения как ${a} не подставляет как слово hello worldДо тех пор, пока это не будет изменено echo ${a} в

  1. echo $a: Работа
  2. echo $${a}: Работа

$$ означает pid процесса в bash, но почему $$ сделать трюк в ExecStart вероятно, чтобы получить слово hello world?

1 ответ

Решение

Брейс против расширения параметров

То, что вы делаете, это не расширение фигурных скобок, а расширение параметров. Расширение скобки (например, ${1..5} не работает внутри двойных кавычек.

Ваша проблема объяснена двумя оболочками Bash

Расширение параметра работает внутри двойных кавычек, но если подстановка должна происходить в вызываемой оболочке вместо текущей, $ знак должен быть в кавычках.

Рассмотрим этот пример:

a='bye world' ; /bin/bash -c "a='hello world'; echo ${a}"
bye world

против этого:

a='bye world' ; /bin/bash -c "a='hello world'; echo \${a}"
hello world

Применение решения к служебным файлам systemd и почему работает `$$`

Важно помнить, что ваш файл описания службы systemd не выполняется в Bash (как в приведенных выше примерах), поэтому существуют некоторые очень похожие, но слегка отличающиеся правила, см. Документацию для файлов конфигурации модуля обслуживания.

Ваша проблема в том, что, подобно интерактивному Bash в первом примере выше, systemd пытается расширить ${a} которого он не имеет в своем окружении. Как вы уже заметили, $$ это ваше решение, а ссылка выше объясняет почему:

Чтобы передать буквальный знак доллара, используйте "$$".

Это позволяет расширению параметра происходить в оболочке Bash, вызываемой systemd. Таким образом, строка в файле конфигурации должна выглядеть так:

ExecStart=/bin/bash -c "a='hello world'; echo $${a}"
Другие вопросы по тегам