在公司事业部级的shell编程规范里提到了这么一条建议规范:

建议所有在shell中使用反单引号执行bash命令的脚本统一使用$()进行替换 如:echo ls 替换为 echo $(ls)

但Gaopei同学在整改代码的时候便出现了问题,一条shell语句直接终止,真是一条编程规范引发的血案

~ $ echo <code>{{EJS1}}</code>
/dev/sda2 67293180 34201356 33091824 51% windows
~ $ echo $(df | sed 's////g' | tail -n 1)
sed: -e 表达式 #1, 字符 10: 未终止的“s”命令↵

同样的命令用来直接替换是有问题,编程规范也有不规范的时候,问题出在哪里,反引号和$()的区别又是什么? 从告警上来看,必然是sed的匹配规则出来问题,根据自己学的sed知识明显的可以发现问题所在:

sed 's////g'

缺少了一个反斜杠,导致第二个反斜杠作为匹配规则而非字符进行识别,匹配规则出错。正常结果应该为:

~ $ echo $(df | sed 's////g' | tail -n 1) 
devsda2 67293180 34201356 33091824 51% windows

但反引号没有问题的原因是什么呢?通过观察结果发现,反引号的语句只替换了一个反斜杠,$()替换两个反斜杠,咦,难道是反引号可以递归转义特殊字符?

echo <code>{{EJS2}}</code> 
devsda2 67293180 34201356 33091824 51% windows

增加一个反斜杠结果一样 通过上面的可以看到反引号是可以多次转义的,而$()只能转义一次,同时bash默认的也是转义一次,根据KISS原则,编程规范建议强制使用$()而非反引号,同时二者进行相互转换的时候需要注意。


反引号和$()的区别是什么来自于OenHan

链接为:http://oenhan.com/shell-backtick

发表回复