4

当我做类似的事情时:

./foo -uxw --bar something

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

4

6 回答 6

7

每个程序都会解析它的参数。您可能需要对此进行调查getopt,因此答案变为:每个程序通常都依赖于getoptparse arguments

于 2012-08-17T07:19:06.913 回答
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"or '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
于 2012-08-17T07:22:59.657 回答
1

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

于 2012-08-17T07:18:40.423 回答
1

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

于 2012-08-17T07:19:46.443 回答
1

shell 用空格分割命令行,所以程序接收到一个参数列表;但由程序决定它们的含义。通常使用类似的参数解析库getopt来提供帮助。

于 2012-08-17T07:22:50.907 回答
0

程序参数不是 shell 所关心的。

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

虽然这只是一个惯例,而不是法律。最知名的标准通常称为 POSIX 标准,它在这里定义了命令行。

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

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

于 2012-08-17T07:44:59.240 回答