Расширение 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}
в
echo $a
: Работа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}"