最近在调试ubuntu 14.04上的openvswitch服务时,发现openvswitch在upstart里的脚本实现频繁用到了set这样一个shell builtin,代码写的不是很好理解,后来经过查询shell相关文档,终于理解了通过set这个builtin来操作位置变量确实是一个很不错的办法。
bash的info文档中专门有一章节来介绍The Set Builtin,并且由于builtin is so complicated that it deserves its own section,但从本文的角度来看,我们认为set就是用来操作位置变量的,以下用一个简单的示例,就可以很容易的给出set的妙用了。
set -- # --这个特殊的用法来清空位置变量,即用$@来访问位置变量将得到空,除了--,set还有其他很多用法,具体可以查看shell的info文档 set "$@" ls # 用ls来初始化位置变量,ls将被赋值给$1 set "$@" -l # 将$@展开后,与-l一起重新赋值给位置变量,使得ls被赋值给$1,-l给赋值给$@ $@ # 展开位置变量,并执行,等同于执行ls -l命令
从上面的代码示例可以看出,set可以将其后的一串参数赋值给位置变量,从而方便对命令行扩充,支持更好的扩展性,并且由于@这个位置变量全集的通用性,使得在脚本嵌套时,可以方便在被执行的脚本中,对原调用脚本传过来的参数进行进一步的编辑,从而实现更为复杂的应用,比如上述openvswitch的upstart脚本,就在这点上大做了文章。
从这点感觉,bash设计的还是很精妙的,工作中大多数采用C编程,对于shell脚本的编程实践较少,后续需要继续掌握这些细节和强大之处:)