systemd 环境文件中的嵌套变量

systemd 环境文件中的嵌套变量
#File: /home/miles/temp/foo.env

ONE=/one
TWO=${ONE}/two
FULL_PATH=${TWO}/three
#File: ~/.config/systemd/user/foo.service

[Service]
EnvironmentFile=/home/miles/temp/foo.env

# prints ${TWO}/three
# ExecStart=/bin/sh -c 'echo $FULL_PATH'

# prints ${ONE}/two/three
ExecStart=/bin/sh -c 'echo ${FULL_PATH}'
  1. 有没有办法以任意级别的嵌套来扩展变量?

    看来只能扩展了层次深。

    有关的:如何在环境文件中进行两级替换

  2. 为什么在变量周围添加大括号会FULL_PATH进一步扩展一级?

    我希望在这种情况下花括号是可选的。

    要扩展的参数名称或符号可以用大括号括起来,大括号是可选的,但用于保护要扩展的变量免受紧随其后的字符的影响,这些字符可能被解释为名称的一部分。

    https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

    在 systemd 中,看起来大括号只是为了防止在空格上分割单词,这不是本例中的一个因素。

    在命令行上用作"${FOO}"单词的一部分,或作为其自己的单词,在这种情况下,它将被删除并替换为环境变量(如果有)的确切值(包括它包含的所有空格),总是导致恰好是一个参数。在命令行上用作"$FOO"单独的单词,在这种情况下,它将被空格处的环境变量 split 的值替换

    https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html#Command%20lines

答案1

这里的关键点有点微妙,但它存在于您引用的文档中:

使用 ” ${FOO}作为单词的一部分,或者作为它自己的一个词,

使用 ” $FOO作为一个单独的词

$FOO仅当单独用作单词时才会扩展,但是整个带引号的字符串是一个单词,因此$FOO在带引号的字符串内不会被扩展,除非该字符串$FOO中仅包含(因此,'$FOO'"$FOO",但不是"something $FOO")。只有${FOO}用大括号才会在包含其他文本的引用字符串中展开。

因此,您看到的是 systemd/bin/sh -c 'echo ${TWO}/three'${FULL_PATH}/bin/sh -c 'echo $FULL_PATH'的情况下执行$FULL_PATH

在这两种情况下,都没有任何组件进行递归变量扩展。在一种情况下,systemd 替换${FULL_PATH}${TWO}/three,然后 shell 扩展${TWO}.在第二种情况下,systemd 不做任何替换,并且 shell 扩展$FULL_PATH。我不知道有什么方法可以安全地递归扩展变量。

相关内容