为什么“论据可以压倒选项”胜过“论据总是分开的”?

5 options history

受到最近问题的启发为什么特定的选项顺序对 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-fto-f foo变成-ffoo. 但这种行为几乎不存在了。我最近使用的唯一一个执行它的命令是 Java 的jar(它的语法显然受 Sun 版本的taraccepts启发tar cfv tarfile ...)。

Xlib 有一个类似getopt函数 ,XrmParseCommand它允许将选项指定为采用“单独”参数或“粘性”参数。但它处理长选项(-display-geometry等),因此它-fv只是另一个选项,与-f或无关-v。所以这不是我第二种解释的例子。

压扁的 args 何时以及为何占主导地位?是在 POSIX 之前就已经解决了,还是 POSIX 授权决定了这个问题?POSIX 的第一个版本是否与当前版本具有相同的特定要求?古代有没有关于这个主题的存档讨论?

是否有任何其他命令(除了tarjar)支持或历史上支持选项解析的-fv foo=-f foo -v样式?

Cel*_*ada 5

首先,在标准getopt()样式的参数处理中,参数不必针对它们适用的选项进行压缩,它们只是可以。因此,如果-f接受一个参数,则以下两个都是有效的:

command -ffoo positional arguments
command -f foo positional arguments
Run Code Online (Sandbox Code Playgroud)

你所说的“第二种解释”实际上非常非常罕见。就我现在所能想到的,tar并且mt是唯一以这种方式工作的现存命令......而且,正如你提到的,jar,但这只是因为它模拟tar. 这些命令处理参数的方式与标准getopt()风格大不相同。选项前面甚至没有-!我不能肯定为什么很少使用它,但我猜这是因为很难说出哪些选项与哪些参数相匹配。例如,如果bd采取论点,但ace不这样做,那么你有这样的:

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 landm不带参数) 的参数,或者fooandbar可能和, say mand pwhilebaz是一个位置参数......或许多其他可能的组合。