强制 bash 扩展从文件加载的字符串中的变量

新手上路,请多包涵

我正在尝试研究如何使 bash (强制?)扩展字符串中的变量(从文件中加载)。

我有一个名为“something.txt”的文件,内容如下:

 hello $FOO world

然后我跑

export FOO=42
echo $(cat something.txt)

这返回:

    hello $FOO world

即使设置了变量,它也没有扩展 $FOO。我无法评估或获取文件 - 因为它会尝试执行它(它不是可执行的 - 我只想要插入变量的字符串)。

有任何想法吗?

原文由 Michael Neale 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 806
2 个回答

我偶然发现了我认为是这个问题的答案: envsubst 命令:

 echo "hello \$FOO world" > source.txt
export FOO=42
envsubst < source.txt

这输出: hello 42 world

如果您想继续处理文件中的数据 destination.txt ,请将其推回到这样的文件中:

 envsubst < source.txt > destination.txt

如果它在您的发行版中尚不可用,则它位于 GNU 软件包中 gettext

@Rockallite

  • 我写了一个小包装脚本来处理“$”问题。

(顺便说一句,envsubst 有一个“功能”,在 https://unix.stackexchange.com/a/294400/7088 解释了仅扩展输入中的一些变量,但我同意转义异常更多方便的。)

这是我的脚本:

 #! /bin/bash
      ## -*-Shell-Script-*-
CmdName=${0##*/}
Usage="usage: $CmdName runs envsubst, but allows '\$' to  keep variables from
    being expanded.
  With option   -sl   '\$' keeps the back-slash.
  Default is to replace  '\$' with '$'
"

if [[ $1 = -h ]]  ;then echo -e >&2  "$Usage" ; exit 1 ;fi
if [[ $1 = -sl ]] ;then  sl='\'  ; shift ;fi

sed 's/\\\$/\${EnVsUbDolR}/g' |  EnVsUbDolR=$sl\$  envsubst  "$@"

原文由 LenW 发布,翻译遵循 CC BY-SA 4.0 许可协议

许多使用 evalecho 的答案都可以解决问题,但是会中断各种事情,例如多行,尝试转义 shell 元字符,在模板内转义不打算被 bash 等扩展。

我遇到了同样的问题,并编写了这个 shell 函数,据我所知,它可以正确处理所有内容。由于 bash 的命令替换规则,这仍然只会从模板中删除尾随换行符,但只要其他所有内容保持不变,我从未发现这是一个问题。

 apply_shell_expansion() {
    declare file="$1"
    declare data=$(< "$file")
    declare delimiter="__apply_shell_expansion_delimiter__"
    declare command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter"
    eval "$command"
}

例如,您可以将它与 parameters.cfg 一起使用,它实际上是一个只设置变量的 shell 脚本,以及 template.txt 这是一个使用这些变量的模板:

 . parameters.cfg
printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt

在实践中,我将其用作一种轻量级模板系统。

原文由 wjl 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题