Linux进程与命令行选项及参数
- 命令行参数管理
在Linux下运行的程序多数是带参数的,例如ls命令:
ls //不带参数的ls命令
ls -l //带-l参数的ls命令
一般来说,所有程序代码都是从main函数开始执行的,main函数的原型是:
int main(int argc, char *argv[],char *envp[]);
由以上可以看出,main()是可以带参数的,在程序中可以直接使用,这样使程序可以在不同的环境或者条件下选择性执行,同时,该函数也可以有返回值。main()函数参数结构如图所示。
argc是命令行参数的数目(这个值包含命令本身,如果后面没有参数,则argc=1)。
argv是一个指针数组,其各成员依次指向各参数,即argv[0],指向命令本身,argv[1]指向第一个参数“-l”,指针数组的最后一个成员为NULL,表示参数结束。 - 命令行参数识别
读者会发现,平时使用多个参数时,如果有多个参数,参数的顺序是随意的,不会刻意让某个参数处于第一或者第二的位置,为适应这种需要,Linux提供了函数getopt()和getlongopt()识别命令行参数。
(1) getopt获取命令行参数
getopt()函数用来解析命令行参数,该函数声明如下:
extern int getopt (int _argc, char *const *_argv, const char *optstring);
其第一个参数为命令参数的个数(argc),第二个参数为指向这些参数的数组(argv),第三个参数为所有可能的参数字符串(optstring)。
getopt函数的第三个参数optstring可以是下列元素。
- 单个字符,这种表示选项。
- 单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg(一个全局变量)。
- 单个字符后跟两个冒号,表示该选项后可以跟一个参数,也可以不跟参数。参数必须紧跟在选项后不能以空格隔开,该参数的指针赋给optarg。
例如,如果optstring=“ab:c::d::”,命令行参数如下所示:
./getopt -a -b host -chello -d world
在这个命令行参数中,去掉‘-’,a,b,c就是选项。host是b的参数,hello是c的参数。但world并不是d的参数,因为它们中间有空格隔开。
getopt()成功执行后将返回第一个选项,并设置如下全局变量。 - optarg:指向当前选项参数(如果有)的指针。
- optind:再次调用getopt()时下一个argv指针的索引。
- optopt:存储不可知或错误选项。
//为了使getopt与调用者进行通信,如果调用者为某个参数赋相应的值,则optarg指向该值
//例如.test -a=10中,a为参数,赋值为10,则optarg指向10
extern char *optarg;
//下一个要扫描参数在列表中的下标值
extern int optind;
//当opterr=0时,getopt不向stderr输出错误信息
extern int opterr;
//当命令行选项字符不包括在optstring中或者选项缺少必要的参数时
//该选项存储在optopt中,getopt返回‘?’
extern int optopt;
返回值:每执行一次,如果成功,getopt函数将返回查找到的命令行输入的参数字符,并更新系统全局变量,默认情况下,getopt会重新排列命令行参数的顺序,所有不可知或错误的命令行参数都排到最后,因此,当没有其他参数供解析或者出错时,getopt将返回-1,同时optind存储第一个未知或出错选项的下标。
(2)getopt应用示例
以下是一个使用getopt()函数的示例程序,在此程序中,可以有a,b,c 3个选项,其中b必须带参数,而c可以带参数或者不带,此程序用来解析命令行参数,其源代码如下:
(3)getlongopt()获取长命令行参数
getlongopt用来获取长命令行参数,并支持长参数,getlongopt()函数声明如下:
#include<getopt.h>
extern int getlongopt(int _agc, char *const *_argv, const cahr *_shortopts, const struct option *_longopts, int *longind);
第一个参数为当前传递进来的参数个数,第二个参数为当前传递进来的参数列表,第三个参数为当前进程所有可支持短参数的字符串,第四个参数为struct option,标识所有长参数的对应关系。该结构体声明如下
struct option
{
if (defined STDC && STDC) || defined _cplusplus
const char *name; //长参数名
else
char *name;
#endif
int has_arg; //该参数是否需要带参数
int *flag; //标志
int val; //返回参数值
};
此函数的返回情况如下:
- 在使用此函数处理一个参数时,全局变量optarg指向下一个要处理的变量,并返回struct option的第四个成员变量。一般情况下,如果struct option的第三个参数设置为NULL,第三个参数一般设置为该长选项对应的短选项字符值,即返回相应的短选项字符。
- 如果解析完最后一个成员将返回-1.
- 如果getopt_long 遇到一个无效的选项字符,它会打印一个错误消息并返回‘?’。
- 当getopt_long 解析到一个长选项并且发现后面没有参数则返回‘.’,标识缺乏参数。
(4)getopt_long应用示例
下面以一个示例介绍如何使用这个函数,该示例程序需要如下的短选项和长选项:
短选项 长选项 作用
-h --help 输出程序命令行参数说明然后退出
-o filename --output filename 给定输出文件名
-v --version 显示程序当前版本后退出
如果时-h参数,将 列出帮助信息;如果是-o加文件名,将列出文件内容;如果是-v将列出版本信息和提示信息。在此示例程序中,需要先确定两个结构:
①一个字符串,包括所需要的短选项字符,如果选项后有参数,字符后加一个冒号。本例中,这个字符串应该为:
“ho:v”
这是因为-o后面有参数filename,所以字符后面要加“:”。
②一个包含长选型的结构体数组,即struct option,每一个结构体包含四个域。 - 第一个域为长选项字符串。
- 第二个域标识相应选项是否带参数,只能为0,1,2;0代表没有参数、1代表有参数、2表示参数可选。
- 第三个域决定返回结果类型(即flags,一般建议为NULL),如果为NULL,此函数其将返回后一个域(即val,一般都设置为当前获取的短参数值);否则,此函数将返回0。
- 第四个域为函数的返回值,一般设置为对应的短项参数字符的ASCII码值。
另外,结构体数组的最后一个元素全部为NULL和0,标识结束。
例如可以设置如下所示内容:
const struct option long_options[]={
{“help”,0,NULL,‘h’},
{“output”,1,NULL,‘o’},
{“version”,0,NULL,‘v’},
{“help”,0,NULL,‘h’}
};