我偶然发现了用 envsubst 仅替换特定变量的问题,其中一条评论是这个 shell 示例:
envsubst "$(printf '${%s} ' ${!PREFIX*})" < infile
有关完整背景,请参阅原始问题,但本质上它是告诉 envsubst 仅替换那些以字符串“PREFIX”开头的环境变量。
但这是如何工作的?有人可以解释所涉及的不同“步骤”吗?是先读取 infile 吗?什么部分在做 grep/find 之类的事情,所以它可以使用文件中的输入?参数 "${!PREFIX*}" 是某种正则表达式吗?这里有一些子壳魔术吗?
为了更好地理解它,我使用以下内容创建了自己的 infile:
1: ${VAR1}
2: ${VAR2}
3: ${VAR3}
4: ${PREFIX_1}
5: ${PREFIX_2}
6: ${PREFIX_3} ?
7: ${PREFIX_4} + ${PREFIX_5}
8: ${VAR4}
9: bla bla bla
然后我用 echo 替换了 envsubst,得到了这一行:
echo "$(printf '${%s} ' ${!PREFIX*})" < infile
而这个结果:
${PREFIX_1}
所以它有效,但仅适用于第一场比赛。我究竟做错了什么?我希望输出包含所有“PREFIX_”变量 1 到 5。也许当我用 echo 替换 envsubst 时我搞砸了?如果是这样,我如何查看发送到 envsubst 的内容?
${!prefix_*}
是一个 Bash 功能,它扩展到所有以 . 开头的 shell 变量的名称prefix_
。然后printf
在命令替换中将它们打印在大括号内(它会根据需要多次重复格式字符串)。由于命令替换,它们被丢弃在
envsubst
's 命令行上。命令替换的扩展和结果都涉及分词${!prefix_*}
,但与默认值IFS
无关,因为变量名不能包含空格或全局字符。在这里,内容
infile
无关紧要,因为echo
不会从标准输入读取任何内容。那只会打印以 . 开头的变量的名称PREFIX
。