Go语言如何避免flag.Parse()吞掉参数列表中的--分隔符
Go 标准库
flag.Parse() 的 -- 分隔符处理问题与实现方案 直接结论
无法通过标准库提供的配置项,阻止flag.Parse()消费分隔符--。该行为是flag包内置的解析逻辑:遇到第一个内容为--的参数时,会直接跳过该分隔符,把后续所有参数全部归入非选项参数列表,flag.Args()的返回值不会保留--本身的位置信息。
问题背景
最简测试代码的运行结果就能体现该行为:
- 执行
go run . hello,flag.Parse()后打印flag.Args(),输出为[hello] - 执行
go run . -- hello,同样打印flag.Args(),输出依然为[hello]
两类调用完全无法区分。
对于需要封装外部子程序的开发场景,程序的参数规则定义为:myprog [options] [ARG1 ARG2 ...] [-- SUBARG1 SUBARG2...]
即: - 程序自带的可选项、自身位置参数可直接传入
--之后的参数需要原样透传给被包装的子程序
默认解析逻辑完全无法满足该需求:哪怕输入形式为myprog -flag1 val1 -- bar,flag.Args()也只会返回["bar"],完全无法判断该参数属于程序自身的位置参数,还是--之后需要透传的子程序参数。
哪怕可以选择使用---等其他字符串作为参数分隔符,依然可以通过手动预处理的方式实现对标准--分隔符的识别。
可落地实现方案
不需要改用自定义分隔符,仅需在调用flag.Parse()前手动预处理参数即可,所有测试场景均可正常运行:
- 从后往前遍历
os.Args,定位内容为--的元素位置 - 将
--之后的参数切片单独保存,作为需要透传给子程序的参数 - 将
os.Args截断到--之前的范围,再执行正常的flag.Parse()解析流程
该方案可覆盖所有常见调用场景:
- 仅传入程序自身选项
- 传入自身选项与位置参数
- 传入自身参数后通过
--分隔传入子程序参数 - 直接通过
--分隔传入子程序参数
内容的提问来源于stack exchange,提问作者Samuel Phan
相关产品推荐
相关产品推荐

