朋友们好,很高兴再次见面,今天我们来了解一下Shell编程的一个高级语法:如何快速的设置变量
首先我们回顾一下变量,在变量中,只有变量值是可变的(复杂变量能实现变量名与变量值都是可变的),例如下面这个:
name=liumou
echo $name
name=liuyi
echo $name
变量简单演示
下面先带来一个普通场景下的脚本优化,需求如下:
使用shell脚本检测当前系统共有多少内存,已使用内存和剩余内存分别是多少
首先我们先执行内存信息查看的命令:
free -h
查看内存使用信息
然后根据反馈结果编辑脚本,脚本内容如下:
total=`free -h | awk 'NR==2{print}' |awk '{print $2}'`
used=`free -h | awk 'NR==2{print}' |awk '{print $3}'`
free=`free -h | awk 'NR==2{print}' |awk '{print $4}'`
echo -e "本机总内存: [ $total ]
当前已使用: [ $used ]
当前还剩余: [ $free ]"
执行结果:
使用脚本检测内存信息
可以看出来,当前的脚本是没有任何问题的,但是这样的写法显得太低级了(每个变量都要另起一行),那么高级一点的语法应该怎样来呢?这时候用上awk的printf功能就行了
我们首先执行下面这条命令看看:
free -h | awk 'NR==2{print}' |awk '{printf("t=%s\nu=%s\nf=%s\n"), $2,$3,$4}'
然后得出的结果是这样的:
从结果可以看到,此时的输出结果就是一条条的赋值语句,然后我们直接打印变量名看看:
这时候我们可以发现,虽然在上一条命令的输出结果中全部都是赋值语句,但是直接打印变量名却没有任何反应,那这时候我希望输出的结果直接进行赋值应该怎么做呢?
第一种方式:写入文件再执行
free -h | awk 'NR==2{print}' |awk '{printf("t=%s\nu=%s\nf=%s\n"), $2,$3,$4}' > var.sh
source var.sh
执行结果:
这种方式虽然能够实现需求,但是还是太麻烦了,那么最简单的方式就是第二种啦!
第二种方式:eval二次检测
eval二次检测时啥意思呢?也就是说当我们执行了下面这条命令的时候:
free -h | awk 'NR==2{print}' |awk '{printf("t=%s\nu=%s\nf=%s\n"), $2,$3,$4}'
这条命令就相当于一个变量名,而输出的值则是一个变量值,而二次检测就是对第一次的变量值进行二次运算,也就是把下面这段内容当作命令再执行一次:
t=3.7G
u=604M
f=692M
那么怎么用呢?其实很简单,只需要在前面加个eval,然后之前的命令使用反引号包含即可,命令如下:
eval `free -h | awk 'NR==2{print}' |awk '{printf("t=%s\nu=%s\nf=%s\n"), $2,$3,$4}'`
执行结果如下:
eval实现变量快速赋值
所以最终的优化脚本就是:
版本1:
eval `free -h | awk 'NR==2{print}' |awk '{printf("t=%s\nu=%s\nf=%s\n"), $2,$3,$4}'`
echo -e "本机总内存: [ $t ]
当前已使用: [ $u ]
当前还剩余: [ $f ]"
版本2:
eval `free -h | sed -n 2p | awk '{printf("t=%s\nu=%s\nf=%s\n"), $2,$3,$4}'`
echo -e "本机总内存: [ $t ]
当前已使用: [ $u ]
当前还剩余: [ $f ]"
执行结果:
版本1
版本2
当然,eval能做的事情远不是这个快速赋值那么简单,想了解更多高级的shell语法请关注我吧