受到最近问题的启发为什么特定的选项顺序对 tar 命令很重要?,其中提问者了解到为什么tar -cfv test.tar *.jpg
不起作用,我想问一个后续问题:说真的,为什么不呢?
当一个命令有一个-f
需要参数的选项和一个不需要参数的选项时-v
,这个:
cmd -fv foo
Run Code Online (Sandbox Code Playgroud)
可以用两种不同的方式解释:v
是-f
选项的参数并且foo
是非选项参数,或者foo
是选项的参数-f
并且-v
选项存在。第一种解释是 POSIX 的getopt()
作用,所以有很多命令都是这样的。
我一直更喜欢第二种解释。将所有选项打包在一起(无论它们是否接受参数)似乎比foo
将-f
to-f foo
变成-ffoo
. 但这种行为几乎不存在了。我最近使用的唯一一个执行它的命令是 Java 的jar
(它的语法显然受 Sun 版本的tar
accepts启发tar cfv tarfile ...
)。
Xlib 有一个类似getopt
函数 ,XrmParseCommand
它允许将选项指定为采用“单独”参数或“粘性”参数。但它处理长选项(-display
、-geometry
等),因此它-fv
只是另一个选项,与-f
或无关-v
。所以这不是我第二种解释的例子。
压扁的 args 何时以及为何占主导地位?是在 POSIX 之前就已经解决了,还是 POSIX 授权决定了这个问题?POSIX 的第一个版本是否与当前版本具有相同的特定要求?古代有没有关于这个主题的存档讨论?
是否有任何其他命令(除了tar
和jar
)支持或历史上支持选项解析的-fv foo
=-f foo -v
样式?
首先,在标准getopt()
样式的参数处理中,参数不必针对它们适用的选项进行压缩,它们只是可以。因此,如果-f
接受一个参数,则以下两个都是有效的:
command -ffoo positional arguments
command -f foo positional arguments
Run Code Online (Sandbox Code Playgroud)
你所说的“第二种解释”实际上非常非常罕见。就我现在所能想到的,tar
并且mt
是唯一以这种方式工作的现存命令......而且,正如你提到的,jar
,但这只是因为它模拟tar
. 这些命令处理参数的方式与标准getopt()
风格大不相同。选项前面甚至没有-
!我不能肯定为什么很少使用它,但我猜这是因为很难说出哪些选项与哪些参数相匹配。例如,如果b
和d
采取论点,但a
,c
和e
不这样做,那么你有这样的:
command abcde b-argument d-argument
Run Code Online (Sandbox Code Playgroud)
...这意味着在编写命令时,您必须回顾选项字母组,再次阅读,记住您指定的选项需要参数,并以相同的顺序写出参数。那这个呢?
command adcbe b-argument d-argument
Run Code Online (Sandbox Code Playgroud)
糟糕,该d
选项得到了b-argument
,反之亦然。更糟糕的是,如果你看到:
command lmnop foo bar baz
Run Code Online (Sandbox Code Playgroud)
...并且您不熟悉该命令,您不知道哪些参数与哪些选项对应。foo
, bar
, andbaz
可能是n
, o
, p
(and l
andm
不带参数) 的参数,或者foo
andbar
可能和, say m
and p
whilebaz
是一个位置参数......或许多其他可能的组合。