这个variables如何在systemd单元文件中转义工作?

我有一个相当简单的单元文件,用于在CoreOS上运行的服务器实例的发现sidekick服务。 单位文件如下所示:

[Unit] Description=Discovery for frontend server (instance %i) BindsTo=frontend@%i.service After=frontend@%i.service [Service] EnvironmentFile=/etc/environment ExecStart=/usr/bin/bash -c ' \ while true; do \ export PORT=$(docker port frontend%i 80 | sed s/.*://); \ etcdctl set /services/frontend/%i "${COREOS_PRIVATE_IPV4}:$PORT" --ttl 60; \ sleep 45; \ done' ExecStop=/usr/bin/etcdctl rm /services/frontend/%i [X-Fleet] MachineOf=frontend@%i.service 

这工作正常,但花了很多时间才能到达这个阶段,因为如果我将etcdctl行更改为:

 etcdctl set /services/frontend/%i "${COREOS_PRIVATE_IPV4}:${PORT}" --ttl 60; \ 

然后它不起作用 – 它结束了设置一个值,如100.45.218.3:没有端口。 一路上我花了很多时间玩$PORTvariables的不同用途,我不知道为什么我定义的configuration工作。 有一点我在脚本中有这个:

 echo hi $PORT; \ echo "hi $PORT"; \ echo hi ${PORT}; \ echo "hi ${PORT}"; \ 

并得到像这样的日志日志:

 Aug 17 01:05:07 core-01 bash[53694]: hi 32769 Aug 17 01:05:07 core-01 bash[53694]: hi 32769 Aug 17 01:05:07 core-01 bash[53694]: hi Aug 17 01:05:07 core-01 bash[53694]: hi 

基本上我的问题是:这是怎么回事? 这performance在我明白{}在bash脚本中工作。 为什么我可以在COREOS_PRIVATE_IPV4variables上使用COREOS_PRIVATE_IPV4 (从/etc/environment导出,而不是PORT

这在systemd.service(1)中有logging 。 ${PORT}由systemd扩展。 要把$传给shell,你需要写$$ ,所以$${PORT} 。 重要的是这样的:

要传递美元符号,请使用“$$”。 其值在扩展时未知的variables被视为空string。

  1. 如果PORT的内容来自其他bashvariables,那么您将要处理一个indirect reference然后请尝试:

     ${!PORT} 
  2. 我假设你确定你的shell是Bash