背景
需要写个shell脚本,运行在服务器上(centos),处理一些简单的参数。
选型
Node.js/Python要考虑服务器上的版本,临时小脚本,也没必要去规范/统一服务器上的版本。
所以选择Bash。
接下来看到小白文章里都会介绍getopt和getopts,就选了个支持长选项
(--key1 val1 这样的用法)的getopt, 弯路就此开始。
爬坑
坑1
macOS 上的getopt是 BSD UNIX implementation of standalone getopt command
, 也就是说,本地调试好的脚本,拿到Linux上执行,是跑不通的,因为对参数解析的处理不同。
坑2
在macOS上装了 gnu-getopt, 然而拿到Linux上执行,再次跑不通。
研究一番,发现还是有差异,macOS上,gnu-getopt是个命令,而在Linux上,getopt(GNU)是个C库函数,会被getopt命令调用。而这个getopt命令,和gnu-getopt命令的实现效果也不一样。
坑3
新玩意儿上手,从小白建议开始,有时候不坏,但在mac上写shell,拿去Linux上执行,这种要提前有“兼容性”危机感,还是先搜索下“最佳实践”为秒。以往也有在grep(也可能是在sed)的用法上困顿好久的经历。
换做Python可能是个不错的选择,可以提前消除兼容性危机感。在运维群体中的流行度也比Node.js高太多,资料会多很多。
如果是要发行一个对外稳定使用的cli工具,那Golang可能更佳,不需要纠结环境依赖。
BashFAQ 中建议永不使用 getopt, 而应使用getops
Unless it's the version from util-linux, and you use its advanced mode, never use getopt(1). getopt cannot handle empty >arguments strings, or arguments with embedded whitespace. Please forget that it ever existed.
The POSIX shell (and others) offer getopts which is safe to use instead.
而这里,建议如果需要长选项,别用getopts去模拟,有隐患
结论
如果不希望爬这么多坑,推荐使用getopts,因为它在The POSIX shell的范围。
推荐不去使用长选项
(因为getopts对此并没有原生支持)。
过程中找到的好资料:
有疑问加站长微信联系(非本文作者)