Bash 在线工具 | 菜鸟工具 (jyshare.com)
写shell脚本时,有时候想用指针但发现很困难,幸好linux提供了一个eval命令
eval:是一个内置的Linux命令,它的全称是evaluate,意思是评估或执行。它的作用是将它的参数拼接成一个字符串,然后作为输入传递给shell来执行。
它会先对参数进行变量替换,命令替换,算术扩展,和引号移除,然后再执行最终的命令
我们这里主要用到变量替换和引号移除
举个简单例子
a=1
b='a'
echo b=$b
eval b='$'$b
echo b=$b
运行结果
b=a
b=1
运行分析
eval b='$'$b 的运行步骤
1.eval预先运算出$b的值,并将引号移除,变成 b=$a
2.再将上述结果传给shell
3.最后运行 b=$a 赋值命令,得到b=1
同理,我们既然可以获取一级指针的值,也可以获取二级指针,依次类推
a=1
b='a'
c='b'
echo c=$c
eval c='$'$c
eval c='$'$c
echo c=$c
运行结果
c=b
c=1
实战应用
可能有这样的需求,有1个配置文件,但是里面的值是根据环境变化的,我们就先使用变量去占位,待实际运行时,就用变量的值去替换占位的变量名称,那就可以用这类办法去处理
首先,在配置文件中设置占位,约定{{}}表示占位符,node1_ip就是占位的变量名称,脚本在实际运行时,就有一个变量为node1_ip,然后我们就想用变量的实际值来替换它
master_ip={{node1_ip}}
然后,根据占位符规则,取出变量名称node1_ip
b='node1_ip'
紧接着,获取变量node1_ip的实际值,注意$要引起来
act_ip=`eval echo '$'{$b}`
最后,将{{node1_ip}}替换为实际值
sed -i "s#{{node1_ip}}#$act_ip#g" /data/para_file
完整代码
这句代码就是通过eval,获取了变量值的值
第19行: conf_var_value=`eval echo '$'{${conf_var}} 2>&1`
# 假设我们的配置文件路径/data/para_file
echo "master_ip={{node1_ip}}" >/data/para_file
echo "master_user={{node1_user}}" >>/data/para_file
# 假设ip和user的值
node1_ip="192.168.1.12"
node1_user="user01"
# 获取占位变量
tmp_all_var=`awk '{match($0,/({{.*}})/,a);print a[1]}' "/data/para_file"|grep -v ^$|sed 's/}}[^{]*{{/}}\n{{/g'|sed 's/{\s\+/{/g'|sed 's/\s\+}/}/g'|sort -u`
# 将待替换变量转化为数组
tmp_all_var_array=(${tmp_all_var//\r\n/ })
# 循环替换
for each_var in ${tmp_all_var_array[@]}
do
# 去掉{}符号
conf_var=`echo $each_var|sed 's/{//g'|sed 's/}//g'`
# 获取变量的实际值
conf_var_value=`eval echo '$'{${conf_var}} 2>&1`
if [ $? -eq 0 ];then
# 获取成功,则执行替换
sed -i "s#{{$conf_var}}#${conf_var_value}#g" /data/para_file
fi
done
# 查看是否被替换
cat /data/para_file
运行结果
master_ip=192.168.1.12
master_user=user01