IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> linux 下的帮助接口argp_parse()实战 -> 正文阅读

[系统运维]linux 下的帮助接口argp_parse()实战

作者:recommendNps

linux 下的帮助接口argp_parse()

选项能够改变程序的运行轨迹,而帮助系统需要让用户知道有哪些选项可以使用。
gnu 的帮助系统已经为我们写了很多代码,我们只需要调用argp_parse 函数就可以了.
----------------------------------------
argp_parse() 的基本用法
----------------------------------------
argp_parse需要我们定义一个帮助表,看一下它的调用参数: 6个,挺复杂

int argp_parse (const struct argp * __argp,
?? ??? ??? ??? int __argc, char ** __argv,
?? ??? ??? ??? unsigned __flags, int * __arg_index,
?? ??? ??? ??? void * __input);

第1项是一个结构指针
第2项,第3项argc,argv 就是c语言的命令行参数选项.
第4项, flag.
第5项,index, 第6项input
不明白的可以都设置为0,看看是什么情况.

#include <stdio.h>
#include <argp.h>
int main (int argc, char **argv) 
{
	return argp_parse (0, argc, argv, 0, 0, 0);
}

argc,argv不能填0, 否则会段错误.
该程序编译运行后,果然能很好的工作,出现了默认的帮助菜单,与标准linux的显示风格一致.
现在想加入版本信息.只需要加一个全局变量即可.
const char *argp_program_version = "version 1.0";
工作的也很好!
这些都是系统的东西,我们基本上没有做什么.
注意这里所说的系统就是库,相对于用户来说的,以后都沿用这种说法.


现在我们想加入一个自己的选项, 先定义一个选项表,里面包含一个选项.
struct argp_option options[] =
{
?? ?{ "dot", 'd', "NUM", OPTION_ARG_OPTIONAL, "Show some dots on the screen"},
?? ?{ 0 },
};

选项还是容易理解的,如下定义,其中1,3,5项都是字符串,第1项是长选项名称
? type = struct argp_option {
????? const char *name;
????? int key;
????? const char *arg;
????? int flags;
????? const char *doc;
????? int group;
? }
? 第3项是参数类型,"NUM" 是数字型参数
? 第5项是帮助信息.
? 第2项是一个字符,所以用''括住,它是作为key来使用的, 各个选项是靠它来区分的.
? 第4项flags, OPTION_ARG_OPTIONAL 表示该参数是可选的(可以跟参数或不跟参数)
? 第5项group, 是分组数值,后面使用时就理解了.

那这个options 表如何使用呢?
后面,有一个重要的结构要出场了,它就是 struct argp, 有7个成员
type = struct argp {
? const struct argp_option *options;
? argp_parser_t parser;
? const char *args_doc;
? const char *doc;
? const struct argp_child *children;
? char *(*help_filter)(int, const char *, void *);
? const char *argp_domain;
}
这个结构太复杂,要慢慢通过实例来理解. 不过不理解的可以先置空.
第一项 options 指针显然指向我们定义的argp_option 数组
第2项 parser 是一个回调函数。 你想,当我们定义了一个选项,通过调用 --help系统把帮助信息给我们显示了出来.
?? ?当我们从命令行输入自定义选项时,怎样解释这个选项,也是需要我们来解释的,所以我们要定义这个解释函数。
第3项,4项都是字符串,用用就知道了,其它都置0先不管。

#include <stdio.h>
#include <stdlib.h>
#include <argp.h>
const char *argp_program_version = "version 1.0";
struct argp_option options[] = 
{
	{ "dot", 'd', "NUM", OPTION_ARG_OPTIONAL, "Show some dots on the screen"},
	{ 0 },
};

//key 是命令行中传入的选项的key, 如果该key在options表中定义了参数,arg传递的是命令行中的选项参数.
static int parse_opt (int key, char *arg, struct argp_state *state)
{
	switch (key)
	{
		case 'd': 
		{
			unsigned int i;
			unsigned int dots = 1;
			if (arg != NULL) dots = atoi (arg);
			printf("you input option d number is :%d\n",dots);
			for (i = 0; i < dots; i++) printf ("."); 
			printf("\n");
			break;
		}
	}
	return 0; //很关键,否则无信息提示了!!
}

struct argp argp = {options, parse_opt, "<param1>,<param2>" }; //参数3是跟在使用提示的字符串

int main (int argc, char **argv) 
{
	return argp_parse (&argp, argc, argv, 0, 0, 0);
}

"have a rest!", 目前只定义了一个可选参数OPTION_ARG_OPTIONAL, 类型为"NUM", 工作运行良好, 已经可以应付一般的帮助要求了.
解释一下吧,为什么设置了argp_program_version 就能显示出版本号? argp_parse 是怎样得知信息的?
解释清这个问题,需要刨老底了.
我查看了它的库代码,原来如此. (库代码请参考链接下载)
./gnu/argp-pv.c|25| const char *argp_program_version
./gnu/argp.h|448| extern const char *argp_program_version;

使用时:
????? if (argp_program_version)
?? ?? {
?? ? ??? ?....
?? ?? }
就是说,库里边定义了argp_program_version变量,但它的值是NULL,如果用户也定义了argp_program_version,并且不为0,
那应用就会链接你定义的变量, 由于其不为0, 所以就可以添加版本显示选项了.

----------------------------------------
argp 的高级用法
----------------------------------------
1. 介绍2个key参数: ARGP_KEY_ARG,ARGP_KEY_END, 用来处理参数
?? ?我们知道,命令行除了可以带选项,还可以带参数,每当系统分析到参数时,就会回调parse_opt, 并传递key参数为ARGP_KEY_ARG,
?? ?当所有参数处理完时,传递ARGP_KEY_END key 参数
??? ?在parse_opt 函数中,会有如下分支
?? ?case ARGP_KEY_ARG
?? ?case ARGP_KEY_END
2. 添加分组信息,使输出帮助信息更加明了
参考下面程序:

#include <stdio.h>
#include <stdlib.h>
#include <argp.h>
const char *argp_program_version = "version 1.0";
struct argp_option options[] = 
{
    { 0, 0, 0, 0, "Program Options:", 7},		//自定义信息这里定义为7
	{ "dot", 'd', "NUM", OPTION_ARG_OPTIONAL, "Show some dots on the screen"},
    { 0, 0, 0, 0, "Informational Options:", -1},  //系统help 信息属于-1分组
	{ 0 },
};

static int parse_opt (int key, char *arg, struct argp_state *state)
{
	int *arg_count = state->input;
	switch (key)
	{
		case 'd': 
			{
				unsigned int i;
				unsigned int dots = 1;
				if (arg != NULL) dots = atoi (arg);
				for (i = 0; i < dots; i++) printf ("."); 
				printf("\n");
				break;
			}
		case ARGP_KEY_ARG:
			(*arg_count)--;
			if (*arg_count >= 0) printf (" %s", arg);
			break;
		case ARGP_KEY_END:
			printf ("\n");
			if (*arg_count >= 4) argp_failure (state, 1, 0, "too few arguments");
			else if (*arg_count < 0) argp_failure (state, 1, 0, "too many arguments");
			break;
	}
	return 0; //很关键,否则无信息提示了!!
}

struct argp argp = {options, parse_opt, "[param1 [param2 [param3 [param4]]]]" };

int main (int argc, char **argv) 
{
	int arg_count = 4;
	return argp_parse (&argp, argc, argv, 0, 0, &arg_count); //第5项input, 会传递给回调函数的state->input
}

第6个参数你可以传递一个整数,也可以传递一个结构以包含更多信息.
argp_failure 函数实际上类似于printf, 不过它有统一的,标准的外观和感觉.

先介绍到这里吧.
1.介绍了struct argp_option 及其6个成员.
2.介绍了struct argp 7个成员中的3个成员
3.介绍了argp_parse函数6个参数中的4个参数

以后有需要再扩充:

参考1: http://nongnu.askapache.com/argpbook/step-by-step-into-argp.pdf
参考2: https://blog.csdn.net/sinat_38816924/article/details/122180938#t10 (对英文版的翻译)
参考3: gnu 库代码

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:56:36  更:2022-10-22 21:58:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年9日历 -2024/9/19 9:25:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码