术语之间的区别:“选项”,“参数”和“参数”?

115
这些术语:“option”、“argument”和“parameter”有何区别? 在man页面中,这些术语似乎经常被交替使用。

这些术语与 Shell 无关:在调用类似于 execv 的系统调用时,可以通过将文字 argv 数组作为参数传递到程序的执行时间来传递参数,而完全不涉及 Shell。 - Charles Duffy
1
关于man页面和shell,POSIX定义了所有这些术语及更多内容 - The Quark
3个回答

200

一个命令被拆分为一个名为arguments的字符串数组。参数0通常是命令名称,参数1是命令后面的第一个元素,依此类推。这些参数有时称为位置参数

$ ls -la /tmp /var/tmp
arg0 = ls
arg1 = -la
arg2 = /tmp
arg3 = /var/tmp

选项是一种已记录1参数类型,用于修改命令的行为,例如,-l通常表示“长”,-v表示详细信息。 -lv是将两个选项组合成一个单一参数。还有一些长选项 ,例如--verbose(请参见使用getopts处理长短命令行选项)。如其名称所示,选项通常是可选的。然而,也有一些带有自相矛盾的“强制选项”的命令。

$ ls -la /tmp /var/tmp
option1= -l
option2= -a

参数是提供信息给命令或其中一个选项的参数,例如在-o file中,file-o选项的参数。与选项不同,选项的可能值在程序中是硬编码的,而通常情况下参数不是,因此用户可以使用任何适合自己需求的字符串。如果您需要传递一个看起来像选项但不应被解释为选项的参数,则可以在命令行的开头用双破折号分隔它:--2

$ ls -la /tmp /var/tmp
parameter1= /tmp
parameter2= /var/tmp

$ ls -l -- -a
option1    = -l
parameter1 = -a

Shell参数 是指在shell上下文中存储一个值的任何东西,包括位置参数(例如 $1, $2...),变量(例如 $foo, $bar...)和特殊字符参数(例如 $@)。

最后,还有子命令,也称为函数或者(低级)命令,它们与“元命令”一起使用,可以嵌入多个独立的命令,例如 busyboxgitapt-getopenssl 等。对于它们,您可能会在子命令之前有全局选项,并在子命令之后有特定于该子命令的选项。与参数不同,可能的子命令列表是硬编码在命令本身中的。

$ busybox ls -l
command            = busybox
subcommand         = ls
subcommand option1 = -l

$ git --git-dir=a.git --work-tree=b -C c status -s
command            = git
command option1    = --git-dir=a.git
command option2    = --work-tree=b
command option3    = -C c
subcommand         = status
subcommand option1 = -s
注意,一些命令(如testtarddfind)的参数解析语法比先前描述的更为复杂,并且它们的某些或所有参数可以被解析为 expressionsoperandskeys 或类似的特定于命令的组件。
同时,请注意,尽管可选变量赋值和重定向也会被 shell 处理进行波浪线扩展、参数扩展、命令替换、算术扩展和引号去除,但因为它们在命令实际调用并传递其参数时已经消失,所以不会被考虑在我的回复中。 1 我本应写成“通常有文档记录”,因为未记录的选项仍然是选项。
2 双破折号功能需要程序实现。

1
@user1534664,我没有在回复的范围内包含这些可选变量分配,因为它们不会被执行的命令视为参数。出于同样的原因,我也没有考虑重定向,但你是正确的,从shell解释器的角度来看,这些分配会像其他参数一样进行波浪线扩展、参数扩展、命令替换、算术扩展和引号删除的预处理。 - jlliagre
@jlliagre,你提供的定义有参考资料吗?当我在Bash手册中查找这些术语时,发现它们的定义与你提供的稍有不同。然而,手册并没有特别提到长选项等概念,所以也许有更好的参考资料? - joelostblom
1
@copsOnRoad,“c”实际上是第三个选项(其参数)的一部分,答案已修正。谢谢! - jlliagre
1
@CopsOnRoad 这里有一个空格。事实是,git选项“-c”需要一个参数。你不能仅仅通过查看命令行来猜测它的含义。命令文档将会告诉你期望的内容。有些命令支持连续的子命令,这可能是一个子命令,然后是一个子子命令。命令开发者可以自由决定这一点。 - jlliagre
1
虽然这并不重要,但从技术上讲,即使没有记录,选项仍然是一个选项。其他选项也可能如此。至于使用“--”禁用选项:这取决于程序。它可能没有编程支持,但许多工具确实使用了这个功能。非常好的答案,提到了一些程序需要必需的选项,做得很好。 - Pryftan
显示剩余3条评论

17
在典型的Unix命令的man页面中,经常使用参数(argument)、选项(option)和参数(parameter)这些术语。在最低层次上,我们有argument,包括(文件系统路径到)命令本身。
在shell脚本中,您可以使用特殊变量$0..$n来访问参数。其他语言也有类似的访问方式(通常是通过名为argv的数组)。
如果需要,参数可以被解释为选项(options)。如何完成这个过程取决于具体实现。您可以自己编写代码,例如shell(如bash)脚本可以使用提供的getopts或getopt命令。
通常,这些命令将以连字符(-)开头的参数定义为选项,某些选项可能会使用后续参数作为其参数。更强大的解析器(如getopt)支持混合短格式(-h)和长格式(--help)选项。
通常,大多数选项使用零个或一个参数。这些参数有时也被称为值(values)。
程序代码中支持的选项(例如在shell脚本中调用getopts时)。在消耗完选项后的所有剩余参数通常被称为位置参数(positional parameters),当它们给出的顺序很重要时(与通常可以用任何顺序给出选项相反)。
同样,脚本通过如何消耗和使用它们来定义位置参数。
所以一个典型的命令:
$ ls -I README -l foo 'bar car' baz

有七个参数:/usr/bin/ls-IREADME-lfoobar carbaz,可以通过$0$6访问。其中-l-I被解释为选项,后者有一个参数(或)为README。剩下的是位置参数foobar carbaz)。

选项解析可能会通过移除已经使用的选项(例如使用shiftset)来更改参数列表,因此只剩下位置参数,并且可以通过$1..$n后续访问。


6
由于该问题被标记为“bash”,我查找了Bash手册中相关的部分。我将这些部分列为下面的引用段落,以及我的一句话总结。

参数

命令后面的所有内容都是参数。

简单的shell命令(如echo a b c)由命令本身和由空格分隔的参数组成。

简单命令是最常遇到的命令类型。它只是一系列由空格分隔的单词,以 shell 的控制运算符之一结束(请参阅定义)。第一个单词通常指定要执行的命令,剩余的单词是该命令的参数。

参数

在函数执行期间,参数称为参数。

当执行函数时,函数的参数在其执行期间成为位置参数

参数是存储值的实体。它可以是名称、数字或下面列出的特殊字符之一。变量是由名称表示的参数。

位置参数是由一个或多个数字表示的参数,除了单个数字 0。当调用 shell 时,位置参数从 shell 的参数中分配,并可以使用 set 内置命令重新分配。位置参数 N 可以被引用为 ${N},或者当 N 由一个数字组成时可以被引用为 $N。

选项

没有专门的部分定义选项是什么,但它们在整个手册中被称为带连字符前缀的字符。

-p选项将输出格式更改为符合POSIX规范的格式。


在函数执行期间,参数被称为参数。这并不完全准确,“参数”不仅仅是“参数”的另一个名称。更确切地说,参数中存储了参数(更精确地说是位置参数)。更一般地,如引用部分所述,参数存储值的实体参数是指在命令行中跟随命令名称的选项、选项参数或操作数(请参见此处)。 - The Quark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接