shell 脚本的跨平台 getopt
我刚刚发现 getopt
不是跨平台的(特别是对于 FreeBSD 和 Linux)。此问题的最佳解决方法是什么?
I've just found out that getopt
is not cross-platform (in particular for FreeBSD and Linux). What is the best workaround for this issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
getopt 命令本质上有两个版本:原始版本和 GNU 增强版本。 GNU 增强版向后兼容原始版本,因此如果您只使用原始版本的功能,那么两者都可以使用。
检测 getopt 的可用版本
您可以检测哪个版本可用,如果 GNU 增强版可用,则使用增强功能;如果 GNU 增强版不可用,则限制自己使用原始功能。增强版有一个
-T
选项用于测试哪个版本可用。考虑使用内置 shell 命令
getopts
(带有“s”),因为它更便携。但是,getopts
不支持长选项(例如--help
)。如果您喜欢长选项,请使用
getopt
并使用上面的测试来查看getopt
的GNU增强版本是否可用。如果增强版本不可用,脚本可以正常降级为使用getopt
的原始版本(不支持长选项名称,也不支持空格)或使用getopts
> (不支持长选项名称)。正确使用 GNU 增强的 getopt
让 GNU 增强版本正确处理带有空格的参数是很棘手的。其实现方式如下:
秘诀是使用
"$@"
,其中双引号非常重要(在第 1 行中),并eval
设置 命令(第 6 行)。因此,可以检测和处理
getopt
引发的错误,对getopt
的调用与eval
分开进行,两者通过 ARGS 变量链接。完整的工作示例
该示例可以从 https://gist.github.com 下载/hoylen/6607180
维基百科关于 getopts 的条目上的比较表比较了不同的功能。
There are essentially two versions of the
getopt
command: the original version and the GNU enhanced version. The GNU enhanced version is backward compatible with the original version, so if you only use the features of the original version it will work with both.Detect which version of getopt is available
You can detect which version is available and use the enhanced features if the GNU enhanced version is available, and limit yourself to the original features if the GNU enhanced version is not available. The enhanced version has a
-T
option for testing which version is available.Consider using built-in shell command
getopts
(with an "s") instead, because it is more portable. However,getopts
does not support long options (e.g.--help
).If you like long options, use
getopt
and use the above test to see if the GNU enhanced version ofgetopt
is available or not. If the enhanced version is not available, the script can gracefully degrade to either using the original version ofgetopt
(with no support for long option names and no whitespace support) or usinggetopts
(with no support for long option names).Using GNU enhanced getopt properly
Getting the GNU enhanced version to process arguments with whitespace properly is tricky. Here's how it is done:
The secret is to use
"$@"
where the double quotes are very important (in line 1), and toeval
the set command (in line 6).So errors raised by
getopt
can be detected and handled, the call togetopt
is done separately from theeval
with the two linked by the ARGS variable.Complete working example
This example can be downloaded from https://gist.github.com/hoylen/6607180
The comparison table on Wikipedia's entry on getopts compares the different features.
使用
getopts
(带有“s”)。根据 Bash 常见问题解答 35:
Use
getopts
(with an "s").According to Bash FAQ 35:
getopt
的基本语法是跨平台的。Basic syntax for
getopt
is cross-platform.Bash 内置 getopts 函数可用于可移植地解析短选项和长选项,请参阅:
在 bash shell 脚本中使用 getopts 获取长和短命令行选项
The Bash builtin getopts function can be used to parse short and long options portably, see:
Using getopts in bash shell script to get long and short command line options