Bash Systemd ExecStart 中的大括号扩展
Bash Brace Expansion in Systemd ExecStart
以下测试在CentOS 7.1中进行
在 /usr/lib/systemd/system/
中创建以下文件 test.service
[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}
:工作
$$
表示 bash 中进程的 pid,但为什么 $$
可以在 ExecStart
中使用这个技巧来获得单词 hello world
?
大括号与参数扩展
你做的不是大括号展开,而是参数展开。大括号扩展(例如 ${1..5}
在双引号内不起作用。
你的问题用两个 Bash shells
解释
参数扩展 在双引号内工作,但如果替换应该发生在被调用的 shell 而不是当前的 $
符号需要被引用。
考虑这个例子:
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 中执行(如上面的示例),因此有一些非常相似但略有不同的规则,请参阅 documentation for service unit configuration files.
您的问题是,就像上面第一个示例中的交互式 Bash 一样,systemd 正在尝试扩展其环境中没有的 ${a}
。正如您已经注意到的,$$
是您的解决方案,上面 link 解释了原因:
To pass a literal dollar sign, use "$$".
这允许在 Bash shell systemd 调用时进行参数扩展。所以配置文件中的行应该是:
ExecStart=/bin/bash -c "a='hello world'; echo $${a}"
以下测试在CentOS 7.1中进行
在 /usr/lib/systemd/system/
test.service
[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}
:工作
$$
表示 bash 中进程的 pid,但为什么 $$
可以在 ExecStart
中使用这个技巧来获得单词 hello world
?
大括号与参数扩展
你做的不是大括号展开,而是参数展开。大括号扩展(例如 ${1..5}
在双引号内不起作用。
你的问题用两个 Bash shells
解释参数扩展 在双引号内工作,但如果替换应该发生在被调用的 shell 而不是当前的 $
符号需要被引用。
考虑这个例子:
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 中执行(如上面的示例),因此有一些非常相似但略有不同的规则,请参阅 documentation for service unit configuration files.
您的问题是,就像上面第一个示例中的交互式 Bash 一样,systemd 正在尝试扩展其环境中没有的 ${a}
。正如您已经注意到的,$$
是您的解决方案,上面 link 解释了原因:
To pass a literal dollar sign, use "$$".
这允许在 Bash shell systemd 调用时进行参数扩展。所以配置文件中的行应该是:
ExecStart=/bin/bash -c "a='hello world'; echo $${a}"