以下内容由Deepseek生成,仅作记录
命令行工具的选项(options,也叫“开关”或“标志”)解析有很多约定。POSIX 标准定义了一套“短选项”的语法规范,GNU 项目在此基础上增加了“长选项”等扩展。日常使用的大部分 Linux/Unix 命令都遵循或部分遵循这些惯例。
1. POSIX 短选项惯例
POSIX(Portable Operating System Interface)在《Utility Syntax Guidelines》中定义了命令行工具应遵循的基本语法。
1.1 短选项以单个连字符开头
短选项通常是一个连字符 - 后跟一个字符,例如:
1 | ls -a |
选项名一般是字母或数字。
1.2 无参数短选项可以合并
多个不带参数的选项可以写在一起,只用一个连字符:
1 | ls -la |
但若某个选项需要参数,合并时它会“吞掉”后面的内容作为参数:
1 | grep -in pattern file |
这里的 -in 被解释为 -i -n,因为 -i 和 -n 都不需要参数。如果写成:
1 | grep -on pattern file |
-o 需要参数吗?grep -o 确实不需要。但假设某个工具 foo -o 需要参数,那么:
1 | foo -obar |
通常表示选项 -o,其参数是 bar,而不是 -o -b -a -r。
1.3 选项参数的形式
如果短选项需要参数,参数可以:
- 作为同一个单词中选项后面的部分:
1 | foo -ofilename |
- 或者作为下一个独立的单词:
1 | foo -o filename |
两种形式都符合 POSIX 惯例。但可选参数(optional option argument)通常要求参数紧跟在选项后,避免歧义:
1 | foo -oARG # 可选参数应这样写 |
1.4 选项必须出现在操作数之前
POSIX 规定,选项解析遇到第一个非选项参数(操作数)时停止,后面的内容都视为操作数,即使它们以 - 开头:
1 | command -a arg1 -b |
这里的 -b 会被当作普通操作数,而不是选项,因为它在 arg1 之后。若要改变这种严格顺序,需要 GNU 扩展或特定工具支持。
1.5 -- 终止选项解析
-- 是一个特殊标记,表示“选项到此结束”,后面的所有内容都作为操作数处理,即使以 - 开头:
1 | rm -- -filename |
1.6 单个 - 作为标准输入/输出占位符
很多命令将单独一个 - 作为操作数,表示标准输入或标准输出:
1 | cat file - # 先输出 file 内容,再输出标准输入 |
注意:- 本身通常不作为选项名。
2. GNU 扩展:长选项
GNU 项目在保留 POSIX 短选项的基础上,增加了“长选项”,提高了可读性。
2.1 长选项以两个连字符开头
1 | ls --all |
长选项由字母、数字和连字符组成,通常是一个或多个完整单词。
2.2 长选项参数
带参数的长选项有两种写法:
- 用等号连接:
1 | grep --after-context=5 |
- 用空格分隔:
1 | grep --after-context 5 |
两种形式通常都支持。
若长选项有可选参数,应使用等号形式:
1 | command --color=auto |
2.3 长选项的缩写
GNU getopt_long 允许长选项缩写,只要缩写是唯一的。例如:
1 | ls --all |
如果 --all 是唯一匹配的,--al 可以缩写。但脚本中应尽量使用完整长选项,避免新增选项导致歧义。
2.4 常用 GNU 标准长选项
GNU 建议所有工具支持:
--help:显示帮助信息--version:显示版本信息
这是 GNU 编码规范的一部分。
3. POSIX 与 GNU 选项解析的差异
3.1 选项和操作数的顺序
- POSIX:选项解析在第一个非选项操作数后停止。
- GNU:默认情况下,
getopt_long会“排列”参数,将选项移到操作数前面继续解析,除非设置了环境变量POSIXLY_CORRECT。
示例:
1 | mycmd arg1 -a |
- POSIX 模式:
-a被当作操作数。 - GNU 模式:
-a被识别为选项,arg1最终作为操作数。
GNU 这样做是为了方便用户将选项写在后面,但会打破严格的 POSIX 兼容性。
3.2 长选项
POSIX 不定义长选项。长选项是 GNU 扩展,后来被许多非 GNU 工具接受,但严格 POSIX 环境可能不支持。
4. 命令行选项设计建议
如果你要编写命令行工具,遵循以下约定可以提高一致性和可用性:
短选项用于常用操作,长选项用于可读性。
1
2
3-h, --help
-v, --version
-f, --file=FILE无参数选项可以合并,有参数选项尽量使用独立参数或等号。
避免可选参数,容易造成歧义。始终支持
--结束选项解析。
这样用户可以处理以-开头的文件名。选项在操作数之前。
除非刻意支持 GNU 排列,否则保持传统顺序。使用
--help和--version。
这是 GNU 标准,用户已经习惯。选项名避免使用数字开头,防止与操作数混淆。
POSIX 允许数字,但可读性差。如果需要多个参数,优先用逗号分隔或多次指定选项。
POSIX 惯例是一个选项最多一个参数。
5. 示例
一个兼容 GNU/POSIX 风格的工具调用可能长这样:
1 | mytool --verbose --output=result.txt -- input.txt |
--verbose:长选项,无参数--output=result.txt:长选项带参数--:结束选项input.txt:操作数,即使名字像选项也不解析
等价的短选项形式:
1 | mytool -v -o result.txt -- input.txt |
或合并无参数短选项:
1 | mytool -v -o result.txt -- input.txt |
总结:POSIX 定义了短选项的基本规则,GNU 扩展了长选项和更宽松的参数排列。现代 Linux 工具大多结合两者,遵循“短选项易用、长选项可读”的原则。
