【问题标题】:How to dereference environment variables read from file?如何取消引用从文件中读取的环境变量?
【发布时间】:2021-06-13 05:52:12
【问题描述】:

假设我有一个文件 file.le:

$GNUPG_HOME
$XDG_CONFIG_HOME
$XDG_DATA_HOME

在我的备份脚本中,我想实际上取消引用这些变量(在 rsync 中通过 --include-from=fi.le

$XDG_CONFIG_HOME,应该变成/home/user/.config

我做了一个循环来检查:

while read i; do ls "$i"; done < fi.le

for i in `cat fi.le`; do ls $i; done

它会返回:

ls: 无法访问'$XDG_DATA_HOME': 没有这样的文件或目录

我想它将 '$' 视为 '\$' (转义)。我该如何改变这个?

【问题讨论】:

  • 每一行都只是一个变量名,还是可以和文字混合?
  • 它们不被视为被转义,它们只是被视为数据而不是 shell 语法。或者,换句话说,转义 $ 将阻止它在通常会引入变量替换的上下文中被解释,但从文件读取的数据不是这些上下文之一。

标签: bash variables escaping rsync


【解决方案1】:

envsubst是你的朋友:

$ cd "$(mktemp --directory)"
$ cat > vars.txt <<'EOF'
> $HOME
> $USER
> EOF
$ envsubst < vars.txt 
/home/username
username

【讨论】:

  • 完美地完成了这项工作。方便的是该文件可以包含其他任意字符串,例如绝对路径和 cmets(在 rsync 备份脚本的情况下)。
【解决方案2】:

如果 file.le 只包含环境变量,那么:

while read i; do ls "$i"; done < <(envsubst < fi.le)

【讨论】:

    【解决方案3】:

    去掉开头的$,然后使用间接变量。

    while read i; do
        i=${i/\$/} # remove $
        ls "${!i}" # use `$i` as the name of a variable
    done < fi.le
    

    【讨论】:

      猜你喜欢
      • 2017-03-06
      • 2021-03-12
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多