当我做类似的事情时:
./foo -uxw --bar something
shell是自动解析这些命令,还是每个程序都必须自己进行解析?
答案 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上的正常情况)。
如果操作数以连字符开头会发生什么?答案是大多数程序会将其视为操作数。但是有一个特殊的标记; --
(两个连字符)标记选项列表的结尾,因此后面的任何内容都只是操作数。