【问题标题】:Bash Brace Expansion in Systemd ExecStartSystemd ExecStart 中的 Bash 大括号扩展
【发布时间】:2016-01-10 21:15:56
【问题描述】:

以下测试在 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} 更改为

  1. echo $a:工作
  2. echo $${a}:工作

$$ 表示 bash 中进程的 pid,但为什么 $$ 可以在 ExecStart 中使用技巧来获得 hello world 这个词?

【问题讨论】:

    标签: linux bash centos systemd brace-expansion


    【解决方案1】:

    大括号与参数扩展

    你所做的不是大括号扩展,而是参数扩展。大括号扩展(例如,${1..5} 在双引号内不起作用。

    用两个 Bash shell 解释了您的问题

    参数扩展确实在双引号内起作用,但如果替换发生在被调用的 shell 而不是当前的 shell 中,则需要引用 $sign。

    考虑这个例子:

    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}。正如您已经注意到的,$$ 是您的解决方案,上面的链接解释了原因:

    要传递文字美元符号,请使用“$$”。

    这允许在 systemd 调用的 Bash shell 中进行参数扩展。所以配置文件中的行应该是:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多