当我做类似的事情时:
./foo -uxw --bar something
shell 会自动解析这些命令,还是每个程序都必须自己解析?
每个程序都会解析它的参数。您可能需要对此进行调查getopt
,因此答案变为:每个程序通常都依赖于getopt
parse arguments。
不,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
每个程序都必须自己解析所有参数。用破折号作为前缀只是 Unix 惯例。
不,shell 不解析这些选项。每个程序都必须自己解析它。
shell 用空格分割命令行,所以程序接收到一个参数列表;但由程序决定它们的含义。通常使用类似的参数解析库getopt
来提供帮助。
程序参数不是 shell 所关心的。
(简化的)命令行语法是:命令选项操作数。
选项以连字符(破折号)开头,操作数没有,选项无序,操作数有序。
虽然这只是一个惯例,而不是法律。最知名的标准通常称为 POSIX 标准,它在这里定义了命令行。
您可能会注意到选项是以单个连字符为前缀的单个字符,您的示例显示了两个带多个字符的连字符--bar
。这些被称为长选项,严格来说不是标准的一部分,尽管它们通常用于 GNU 实用程序(Linux 上的正常情况)。
如果操作数以连字符开头会发生什么?答案是大多数程序会将其视为操作数。不过有一个特殊的标记;--
(两个连字符)标记选项列表的结尾,所以后面的只是操作数。