Bash脚本变量解释

问题描述 投票:0回答:3

我有一个文本文件,其中包含对变量的引用,并允许用户设置他们想要的变量格式,比如说

 The date is $DATE
 The time is $TIME

然后我想读取这个文本文件,替换变量,并使用bash脚本将结果打印到stdout。我得到的最接近的是使用“echo”来输出它,

 DATE="1/1/2010"
 TIME="12:00"
 TMP=`cat file.txt`
 echo $TMP

但是,输出最终都在一行上,我不希望在文本文件的每一行的末尾都有\ n。我尝试使用“cat << $ TMP”,但之后没有新行,文本中的变量也没有被值替换。

linux bash shell unix
3个回答
2
投票

您可以使用eval来确保在数据文件中扩展变量:

DATE="1/1/2010"
TIME="12:00"
while read line
do
  eval echo ${line}
done < file.txt

请注意,这允许用户控制文件内容以执行任意命令。

如果输入文件不在您的控制之下,那么更安全的解决方案是:

DATE="1/1/2010"
TIME="12:00"
sed -e "s#\$DATE#$DATE#" -e "s#\$TIME#$TIME#" < file.txt

它假设$DATE$TIME都不包含#字符,并且不应扩展其他变量。


0
投票

比亚当的反应稍微紧凑:

DATE="1/1/2010"
TIME="12:00"
TMP=`cat file.txt`
eval echo \""$TMP"\"

所有这一切的缺点是你最终挤压报价。更好的是使用真实的模板。我不确定如何在shell中执行此操作,因此如果可能的话,我会使用其他语言。模板的好处在于你可以消除Adam提到的那个“任意命令”漏洞,而不用像sed那样编写丑陋的代码。


0
投票

只需引用您的变量以保留换行符。

DATE="1/1/2010"
TIME="12:00"
TMP=$(cat file.txt)
echo "$TMP"

您可以使用变量修改文件中的值 -

while read -r line
do 
   sed -e "s@\$DATE@$DATE@" -e "s@\$TIME@$TIME@" <<< "$line"
done < file.txt

Test:

[jaypal:~/Temp] cat file.txt
The date is $DATE
The time is $TIME
[jaypal:~/Temp] DATE="1/1/2010"
[jaypal:~/Temp] TIME="12:00"
[jaypal:~/Temp] while read -r line; do sed -e "s@\$DATE@$DATE@" -e "s@\$TIME@$TIME@" <<< "$line"; done < file.txt
The date is 1/1/2010
The time is 12:00
© www.soinside.com 2019 - 2024. All rights reserved.