如何在下面的脚本中的多行字符串中正确引用变量?分配MY_INFO=INFO2
不会产生所需的更新输出。
示例脚本:
#!/bin/bash
INFO1="output1"
INFO2="output2"
MY_INFO=INFO1
if [ True ]; then
INFO="
Here are the test results
bbb
ccc
aaa
${!MY_INFO}
"
fi
echo "First:"
echo "$INFO"
MY_INFO=INFO2
echo "Second:"
echo "$INFO"
输出:
First:
Here are the test results
bbb
ccc
aaa
output1
Second:
Here are the test results
bbb
ccc
aaa
output1
期望的输出:
First:
Here are the test results
bbb
ccc
aaa
output1
Second:
Here are the test results
bbb
ccc
aaa
output2
答案 0 :(得分:1)
由于if [ true ]
与if
完全相同,我们可能会省略if ... fi
。
要获取变量的late evaluation,可能存在危险的eval
命令:
#!/bin/bash
INFO1="output1"
INFO2="output2"
MY_INFO=INFO1
INFO="
Here are the test results
bbb
ccc
aaa
\${!MY_INFO}
"
echo "First:"
eval echo \""$INFO"\"
MY_INFO=INFO2
echo "Second:"
eval echo \""$INFO"\"
输出:
First:
Here are the test results
bbb
ccc
aaa
output1
Second:
Here are the test results
bbb
ccc
aaa
output2
答案 1 :(得分:1)
您的INFO字符串在第二次调用时不会再次重新评估,您可以将其转换为函数以接受变量输入,例如......
#!/bin/bash
INFO1="output1"
INFO2="output2"
info() { echo "
Here are the test results
bbb
ccc
aaa
$1
";}
echo "First:"
info "$INFO1"
echo "Second:"
info "$INFO2"
或者,使用变量间接,仍然使用函数
#!/bin/bash
INFO1="output1"
INFO2="output2"
info() { echo "
Here are the test results
bbb
ccc
aaa
${!MYINFO}
";}
echo "First:"
MYINFO=INFO1
info
echo "Second:"
MYINFO=INFO2
info
答案 2 :(得分:1)
在bash 4.3中,您可以使用 namevars (以前称为ksh功能)在变量之间建立链接,这些变量的行为符合您的意图:
var1="hello"
declare -n var=var1 ## declare -n makes var a "namevar" pointing to var1
var="goodbye"
echo "$var1"
...运行时会发出goodbye
。
那就是说,因为你要找的是一个模板,envsubst
是适合这项工作的工具 - 虽然它不支持间接扩展本身:
info_template='Here are the test results
${my_info}'
info_good='Successful test!'
info_bad='Failure!'
result=good
result_var=info_$result
my_info="${!result_var}" envsubst <<<"$info_template"
与eval
不同,envsubst
不容易出现安全漏洞。在显示测试输出时,通过将间接扩展移动到模板本身,可以说这比使代码更轻薄更合适。