Mic*_*ale 75 unix linux bash shell
我试图找出如何使字符串(从文件加载)中的bash(强制?)扩展变量.
我有一个名为"something.txt"的文件,内容如下:
hello $FOO world
Run Code Online (Sandbox Code Playgroud)
然后我跑了
export FOO=42
echo $(cat something.txt)
Run Code Online (Sandbox Code Playgroud)
这会返回:
hello $FOO world
Run Code Online (Sandbox Code Playgroud)
即使变量已设置,它也没有扩展$ FOO.我无法评估或获取文件 - 因为它会尝试并执行它(它不是可执行的 - 我只是想要插入变量的字符串).
有任何想法吗?
Len*_*enW 93
我偶然发现了我认为这个问题的答案: envsubst命令.
envsubst < something.txt
Run Code Online (Sandbox Code Playgroud)
如果你的发行版中还没有它,它就在你的发行版中
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 "$@"
Run Code Online (Sandbox Code Playgroud)
wjl*_*wjl 26
许多答案使用eval和echo工作,但打破各种事情,如多行,试图逃避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"
}
Run Code Online (Sandbox Code Playgroud)
例如,您可以像这样使用它,parameters.cfg它实际上是一个只设置变量的shell脚本,以及一个template.txt使用这些变量的模板:
. parameters.cfg
printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt
Run Code Online (Sandbox Code Playgroud)
在实践中,我将其用作一种轻量级模板系统.
piz*_*zza 18
你可以试试
echo $(eval echo $(cat something.txt))
Run Code Online (Sandbox Code Playgroud)
Tod*_*obs 10
你不想打印每一行,你想要评估它,以便Bash可以执行变量替换.
FOO=42
while read; do
eval echo "$REPLY"
done < something.txt
Run Code Online (Sandbox Code Playgroud)
有关help eval详细信息,请参阅或Bash手册.
另一种方法(看起来很恶心,但我还是把它放在这里):
将 something.txt 的内容写入临时文件,并用 echo 语句包裹它:
something=$(cat something.txt)
echo "echo \"" > temp.out
echo "$something" >> temp.out
echo "\"" >> temp.out
Run Code Online (Sandbox Code Playgroud)
然后将其重新输入到变量中:
RESULT=$(source temp.out)
Run Code Online (Sandbox Code Playgroud)
并且 $RESULT 将全部扩展。但好像大错特错!
不需要临时文件的单行解决方案:
RESULT=$(source <(echo "echo \"$(cat something.txt)\""))
#or
RESULT=$(source <(echo "echo \"$(<something.txt)\""))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45858 次 |
| 最近记录: |