关于以破折号为前缀的命令行参数有什么特别之处吗?

时间:2012-08-17 07:17:15

标签: c linux bash shell unix

当我做类似的事情时:

./foo -uxw --bar something

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

6 个答案:

答案 0 :(得分:7)

每个程序解析其参数。您可能希望查看getopt,以便得到答案:每个程序通常依赖于getopt来解析参数

答案 1 :(得分: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

答案 2 :(得分:1)

每个程序都必须解析所有参数本身。用破折号作为前缀只是Unix惯例。

答案 3 :(得分:1)

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

答案 4 :(得分:1)

shell在空格上拆分命令行,因此程序接收参数列表;但是由程序来决定它们的含义。通常使用解析像getopt这样的库的参数来提供帮助。

答案 5 :(得分:0)

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

(简化)命令行语法是:命令选项操作数 选项以连字符(短划线)开头,操作数不开头,选项不排序,操作数排序。

这虽然只是一项惯例,而不是法律。最着名的标准通常称为POSIX标准,它定义命令行here

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

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