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