花括号被变量赋值后为什么没了扩展功能?

提出问题

今天,小王问了一个脚本问题。

小王问到:

    	这个脚本为啥扫不出所有的

在这里插入图片描述

小红说到:

		ip和端口打印出来是啥

小王

		在脚本里面echo 变量是正常打印的

花狗看了小王的回答之后,说到:

在这里插入图片描述

小红接着说到:

		xargs 无法解析 {20..23}

分析问题

为什么他们有不同的看法吗?
那么我们来分析下他们三个是从哪些角度来思考这个问题的。

小王角度

  • 从脚本portscan.sh里面可以看到,作者通过输入重定向<将文件ip.txt传给命令read读取其文件内容的每一行,由于变量$IFS的作用,可以将文件的每一行拆分多个字段:

    文本第一行:		        192.168.1.1  {20..23}
    
    通过read:               192.168.1.1	-->	IP
    			           {20..23}	     --> PORT	
    			   
    即定义并赋值两个变量:      IP=192.168.1.1
                            PORT={20..23}
                          
    

    好了,到了这里,echo $PORT会打印出来什么呢?

    答案是:

    在这里插入图片描述

    是的,echo{20..23}打印出来了!这是不是跟我们的 echo {20..23}很像呢?
    那这是一样的东西吗?
    在这里插入图片描述

    结果不一样!!

    前面echo $PORT正是小王说 :–在脚本里面echo 变量是正常打印的– 原因。

    他的思考角度:

    echo     $PORT      等价于     echo {20..23}
                |
         值:{20..23}
    

花狗角度

  • 这么一看,好像是这么一回事。跑脚本后却有了 <–这个脚本为啥扫不出所有?–> 这样的问题!

    那是因为变量赋值时PORT={20..23}

               {20..23}         以一串字符整体地传给了        变量PORT,
    实际上:     {20..23}   --->   '{20..23}'        ---->    PORT
    
                               等价于                        输出
    那么:		  echo $PORT   ------->   echo '{20..23}'  ------->  {20..23}
    

    这正是花狗的思考角度。

    那为什么变量赋值的等号右边是以字符形式传给变量名的呢?

    实际上,在shell中,变量数据类型是:
    						*	字符
    						*	数值
    
    也就是说: 从赋值那一刻开始,字符就带上了`引号`,我们的一些特殊字符不再有它的特殊含义,只有字面值的意义。
    

    那真的是这样子吗?

    我们来看一个例子:
    在这里插入图片描述

    这时用 echo 打印出它们值结果会是怎么样呢?

    我们来看一下:

    在这里插入图片描述

    结果是一样的!!!

    这也是印证了 从赋值那一刻开始,字符首尾就带上了引号,我们的一些特殊字符不再有它的特殊含义,只是字面值的意义。

    空口无凭,有何依据呢?

    bash.info 文档中的 shell 参数中提到,变量赋值语句的规则:

    在这里插入图片描述

    得知:变量的值是可以是一个"名字"(即字符字面上的意义),或是一个数字

    而字符是以引号引起来的,只是shll在变量赋值的时候帮你把字符用引号引来:

    在这里插入图片描述

    单双引号也说明了,引号里的字符保留引号中所有字符的字面值,其中包括作为关键字的花括号{}

    在这里插入图片描述

    在这里插入图片描述

    以及 花括号扩展使用文档中的说明:

    在这里插入图片描述

    大致总结的意思:

    	格式正确的`大括号扩展`必须包含未加引号的左括号和右括号,
    	以及至少一个未加引号的逗号或一个有效的序列表达式。
    	任何不正确的大括号展开都将保持不变。
    	
    	`{`  或  `,`  可以用反斜杠括起来,以防止被认为是大括号表达式的一部分。
    	为了避免与参数展开冲突,字符串 `${` 被认为不符合花括号展开条件,
    	并在闭合 `}`之前抑制花括号展开。
    

    综合以上变量赋值、引号作用、花括号作用,得出下面实践结果一样:

    在这里插入图片描述

小红角度

  • 小红的思考角度大概也是清楚了在这脚本中 {20..23}是作为一个整体字符串使用的,而xargs也是没有解析这串字符的功能。

综上总结

  1. shell变量的数据类型是字符和数字。
  2. 用引号括起来的符号扩展(如花括号扩展)是不能进行扩展的。

优化脚本

小王的脚本

小王开始还在纠结能否让加了引号的 {} 进行展开:
在这里插入图片描述

但很快,他用了其他方法实现了他想要的功能:

在这里插入图片描述

在这里插入图片描述

花狗的脚本

花狗认真地看了小王的脚本,起初想:用awk-作为分隔符,再用=~来作匹配判断,结合seq,这就实现了需求!

嗯~角度新颖,甚是巧妙!

但扭头一想:没必要将 -作为分隔符啊!read可以接收多个参数,不止两个呢!而且,这个脚本甚是啰嗦,且阅读性较差,编写脚本应该尽可能地先以阅读性高且代码量少为实践理念。

脚本的阅读性差,会导致其他人甚至作者本身看脚本费劲且容易出错,这也是花狗为什么要认真地看小王脚本的原因!

花狗思考片刻,从seqread两个命令的功能入手,优化了脚本是这样的:

在这里插入图片描述

在这里插入图片描述

给文件增加可读性可以这样子:

在这里插入图片描述

在这里插入图片描述

这样看起来,易读性非常好,代码量也少,非常便于维护。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值