带有短横线前缀的命令行参数是否有特殊含义?

4

当我执行如下操作时:

./foo -uxw --bar something

shell是否自动解析这些命令,还是每个程序都要自己进行解析?


1
惯例上,通常使用单个“-”来表示参数的快捷方式,例如“svn -v”与“svn --version”。 - Andreas Wong
这取决于您所说的“解析这些命令”的含义。如果您具有Windows经验,那么程序只有一个参数(字符串),每个程序都必须将其拆分为参数(某些人可能称之为“解析”)。Unix系统则不同:它们以字节序列的NUL终止形式的指针数组的形式具有无限数量的字符串参数。在运行程序(在这种情况下是shell)中进行拆分。当然,每个参数的解释留给程序来完成。 - fork0
6个回答

7
每个程序都会解析其参数。你可能需要了解一下getopt,这样答案就变成了:每个程序通常依赖于getopt来解析参数

2
不,shell不会为您解析它。每个程序都必须自行解析它。以下代码应该清楚地说明了正在发生的事情。
#include <stdio.h>

int main(int argc, char **argv)
{
    int i;
    printf("argc: %d\n", argc);
    for (i = 0; i < argc; i++) {
        printf("argv[%d] = %s\n", i, argv[i]);
    }
    return 0;
}

让我们编译这个程序。
susam@nifty:~$ gcc args.c -o args

现在让我们运行它并查看输出:
.susam@nifty:~$ ./args
argc: 1
argv[0] = ./args
susam@nifty:~$ ./args foo bar
argc: 3
argv[0] = ./args
argv[1] = foo
argv[2] = bar
susam@nifty:~$ ./args -a foo --b bar
argc: 5
argv[0] = ./args
argv[1] = -a
argv[2] = foo
argv[3] = --b
argv[4] = bar

Shell的唯一作用是将您在命令行中指定的每个参数传递给您的程序。当它将foo bar作为两个单独的参数传递给您的程序时,它将"foo bar"'foo bar'作为单个参数传递给您的程序。是的,所以shell在将参数传递给程序之前会进行某种解析。它将带引号的字符串视为单个参数。这里是一个演示:

susam@nifty:~$ ./args -a foo bar
argc: 4
argv[0] = ./args
argv[1] = -a
argv[2] = foo
argv[3] = bar
susam@nifty:~$ ./args -a "foo bar"
argc: 3
argv[0] = ./args
argv[1] = -a
argv[2] = foo bar
susam@nifty:~$ ./args -a 'foo bar'
argc: 3
argv[0] = ./args
argv[1] = -a
argv[2] = foo bar
susam@nifty:~$ ./args -a "foo bar" 'car tar war'
argc: 4
argv[0] = ./args
argv[1] = -a
argv[2] = foo bar
argv[3] = car tar war

1
每个程序都必须自己解析所有参数。在参数前加破折号只是Unix的惯例。

1

Shell在空格处分割命令行,因此程序会收到一个参数列表;但是由程序决定它们的含义。通常会使用像 getopt 这样的参数解析库来帮助处理。


1
不,shell 不解析这些选项。每个程序都必须自己解析它。

0

程序参数不是shell的关注点。

(简化的)命令行语法为:命令 选项 操作数
选项以连字符(破折号)开头,操作数则不是,选项没有顺序,操作数有顺序。

然而,这只是一种约定,并非法律。最著名的标准通常称为POSIX标准,它定义了命令行在这里

您可能会注意到,选项是带有单个连字符前缀的单个字符,您的示例显示了带有多个字符的两个连字符--bar。这些被称为长选项,并不严格属于标准,尽管它们在GNU实用程序中通常用于Linux(正常情况下)。

如果操作数以连字符开头会发生什么?答案是大多数程序将其视为操作数。但是有一个特殊的标记;--(两个连字符),它标记了选项列表的结尾,因此跟随的任何内容都是操作数。


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