似乎大多数(很多)命令都实现了这样的选项参数:
如果短选项需要选项参数,则选项与选项参数用空格分隔,例如
$ head -n 10
如果长选项需要选项参数,则选项与
=
选项参数用 a 分隔,例如$ head --lines=10
这是某种约定吗?是的,我在哪里可以找到它?此外,这是什么道理?
为什么例如不是
$ head --lines 10
?
似乎大多数(很多)命令都实现了这样的选项参数:
如果短选项需要选项参数,则选项与选项参数用空格分隔,例如
$ head -n 10
如果长选项需要选项参数,则选项与=
选项参数用 a 分隔,例如
$ head --lines=10
这是某种约定吗?是的,我在哪里可以找到它?此外,这是什么道理?
为什么例如不是
$ head --lines 10
?
短选项基本原理在 POSIX Utility Conventions中记录。大多数选项解析器允许将值“附加”到字母 ( -n10
),这主要是因为广泛的历史先例。
长选项的基本原理由 GNU 在其编码标准和getopt_long()
.
很久以前,在很久以前的一个 StackOverflow 中,有一个关于命令选项样式的问题。也许不是一个好问题,但我认为答案拯救了它(但我承认有偏见)。无论如何,它已被删除,所以我将在这里恢复我的答案,因为(a)重新发现答案是一个痛苦的过程,并且(b)它包含与选项相关的有用信息。
您认识多少种不同类型的选项?我能想到很多,包括:
有时必须附加带有可选参数的选项,有时必须遵循“=”符号。POSIX 不支持有意义的可选参数(POSIX getopt() 只允许它们用于命令行上的最后一个选项)。
所有明智的选项系统都使用由双破折号 (' --
') 组成的选项来表示“选项结束” - 以下参数是“非选项参数”(通常是文件名),即使它们以破折号开头。(我认为支持这种表示法是必要的。)请注意,如果您有一个带有需要参数的选项的命令,cmd
那么-f
如果您调用它--
来代替参数 ( cmd -f -- -other
,许多版本的getopt()
将把然后解析为常规选项。也就是说,如果必须将其解释为另一个选项的参数,则不会终止选项。--
-f
-other
--
许多但不是所有程序都接受单破折号作为文件名来表示标准输入(通常)或标准输出(偶尔)。有时,与 GNU ' tar
' 一样,两者都可以在单个命令行中使用:
tar -cf - -F - | ...
第一个单独的破折号表示“写入标准输出”;第二个意思是“从标准输入读取文件名”。
一些程序使用其他约定——也就是说,选项前面没有破折号。其中许多来自最古老的 Unix。例如,'tar' 和 'ar' 都接受不带破折号的选项,所以:
tar cvzf /tmp/somefile.tgz some/directory
该dd
命令opt=value
专门使用:
dd if=/some/file of=/another/file bs=16k count=200
有些程序允许您完全交错选项和其他参数;C 编译器、make 和 GNU 实用程序在环境中没有 POSIXLY_CORRECT 的情况下运行就是示例。许多程序期望选项优先于其他参数。
现代程序,例如git
越来越多地使用基本命令名称 ( git
) 后跟子命令 ( commit
) 后跟选项 ( -m "Commit message"
)。这是由 SCCS 命令的接口所预示的sccs
,然后是cvs
, 并且也被使用svn
(它们都是版本控制系统)。但是,其他大型命令套件会在合适的时候采用类似的样式。
我在不同系统之间没有强烈的偏好。当几乎没有足够的选项时,则具有助记符值的单个字母很方便。GNU 支持这一点,但建议使用前面带有双破折号的多字母选项来支持它。
有些事情我确实反对。最糟糕的情况之一是相同的选项字母使用不同的含义,具体取决于它之前的其他选项字母。在我的书中,这是一个禁忌,但我知道在哪里完成它的软件。
另一个令人反感的行为是处理参数的风格不一致(特别是对于单个程序,但也在一组程序中)。要么需要附加参数,要么需要分离参数(或允许任何一个),但没有一些选项需要附加参数而其他选项需要分离参数。并且对于是否=
可以使用''来分隔选项和参数保持一致。
与许多(与软件相关的)事物一样,一致性比个人决策更重要。
无论您做什么,请阅读TAOUP 的命令行选项并考虑命令行接口标准。(由JF Sebastian添加——谢谢;我同意。)