Linux下解析命令行的标准形参(getopt)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 在Linux下开发时,命令行的使用是必不可少的,经常会在命令行运行各种命令,启动服务,启动应用程序,查看函数用法等等;

一、前言

在Linux下开发时,命令行的使用是必不可少的,经常会在命令行运行各种命令,启动服务,启动应用程序,查看函数用法等等;运行这些命令时都会传入一些参数,比如:

$ ./c_app 127.0.0.1 8888 小明
$ man printf

这些命令行参数解析,Linux提供了一套函数,可以很方便的解析传入的各种参数信息。

这篇文章就介绍如何使用Linux提供的解析函数,完成命令的行的参数解析。

函数原型如下:

#include <unistd.h>
#include <getopt.h>

这3个是全局变量
extern char *optarg;
extern int optind, opterr, optopt;
功能介绍:
optarg——指向当前选项参数(如果有)的指针。  比如: cp 123.c 888/ -fv 、 gcc 123.c -o app
optind——再次调用 getopt() 时的下一个 argv 指针的索引。
optopt——最后一个已知选项。

int getopt(int argc, char * const argv[],const char *optstring);
函数功能: 解析短选项形参. 只能解析单个字符.

函数参数:
int argc   就是main函数传入的argc 
char * const argv[]  就是main函数传入的argv
const char *optstring  将要解析的选项形参格式.
比如: "a:b:c:v"    字母后面跟着冒号就表示该选项形参必须传递参数.
传入形参的时候: a.out -a 666 -b 777 -c 888 -v

返回值:
解析成功就返回当前解析的选项形参的字符. 并且会给全局变量赋值. optarg这个指针就会指向该选项形参后面的数据地址.
如果失败就返回-1   解析错误会返回? 

int getopt_long(int argc, char * const argv[],
         const char *optstring,
         const struct option *longopts, int *longindex);
函数功能:解析长选项形参.
struct option {
   const char *name;   表示要解析的长选项字符串  --abc
   int         has_arg;   0表示不需要参数 1表示必须要 2表示可选
   int        *flag;     一般NULL
   int         val;      当解析到正确的长选项形参的时返回的字符  k
};


int getopt_long_only(int argc, char * const argv[],
         const char *optstring,
         const struct option *longopts, int *longindex);
函数功能:同时支持解析长选项形参和短选项形参.

二、案例代码

2.1 解析命令行的短选项形参

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>

int main(int argc,char **argv)
{
    int c;
    while(1)
    {
        //解析传入的选项参数   ./a.out -a 123 -b 456 -c 789 -v
        c=getopt(argc,argv,"a:b:c:v?");
        if(c==-1)break;
        switch(c)
        {
        case 'a':
            printf("当前的选项形参:a,值:%s\n",optarg);
            break;
        case 'b':
            printf("当前的选项形参:b,值:%s\n",optarg);
            break;
        case 'c':
            printf("当前的选项形参:c,值:%s\n",optarg);
            break;
        case 'v':
            printf("当前版本:1.2.3\n");
            break;
        case '?':
            printf("用法:./a.out [-a 123 -b 456 -c 789 -v] \n");
            break;   
        default:
            break;
        }
    }
    return 0;
}

[wbyq@wbyq linux_c]$ ./a.out -a 123 -b 67 -c 999
当前的选项形参:a,值:123
当前的选项形参:b,值:67
当前的选项形参:c,值:999
[wbyq@wbyq linux_c]$ ./a.out -a
./a.out: option requires an argument -- 'a'
用法:./a.out [-a 123 -b 456 -c 789 -v] 
[wbyq@wbyq linux_c]$ ./a.out -?
用法:./a.out [-a 123 -b 456 -c 789 -v] 
[wbyq@wbyq linux_c]$ ./a.out -v
当前版本:1.2.3
[wbyq@wbyq linux_c]$ 

2.2 解析命令行的长选项形参

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>

struct option opt_list[]=
{
    {"a123",1,NULL,'a'},
    {"b123",1,NULL,'b'},
    {"c123",1,NULL,'c'},
    {"help",0,NULL,'?'},
};

int main(int argc,char **argv)
{
    int c;
    while(1)
    {
        //解析传入的选项参数   ./a.out -a 123 -b 456 -c 789 -v
        c=getopt_long(argc,argv,"a:b:c:v?",opt_list,NULL);
        if(c==-1)break;
        switch(c)
        {
        case 'a':
            printf("当前的选项形参:a,值:%s\n",optarg);
            break;
        case 'b':
            printf("当前的选项形参:b,值:%s\n",optarg);
            break;
        case 'c':
            printf("当前的选项形参:c,值:%s\n",optarg);
            break;
        case 'v':
            printf("当前版本:1.2.3\n");
            break;
        case '?':
            printf("用法:./a.out [-a 123 -b 456 -c 789 -v] \n");
            break;   
        default:
            break;
        }
    }
    return 0;
}

[wbyq@wbyq linux_c]$ ./a.out -a 12345
当前的选项形参:a,值:12345
[wbyq@wbyq linux_c]$ ./a.out --a123 12345
当前的选项形参:a,值:12345
[wbyq@wbyq linux_c]$ ./a.out -?
用法:./a.out [-a 123 -b 456 -c 789 -v] 
[wbyq@wbyq linux_c]$ ./a.out --help
用法:./a.out [-a 123 -b 456 -c 789 -v] 
[wbyq@wbyq linux_c]$ 

2.3 解析复杂的命令行选项形参

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>

struct option opt_list[]=
{
    {"a123",1,NULL,'a'},
    {"b123",1,NULL,'b'},
    {"c123",1,NULL,'c'},
    {"help",0,NULL,'?'},
};

int main(int argc,char **argv)
{
    int c;
    while(1)
    {
        //解析传入的选项参数   ./a.out -a 123 -b 456 -c 789 -v
        c=getopt_long_only(argc,argv,"a:b:c:v?",opt_list,NULL);
        if(c==-1)break;
        switch(c)
        {
        case 'a':
            printf("当前的选项形参:a,值:%s\n",optarg);
            break;
        case 'b':
            printf("当前的选项形参:b,值:%s\n",optarg);
            break;
        case 'c':
            printf("当前的选项形参:c,值:%s\n",optarg);
            break;
        case 'v':
            printf("当前版本:1.2.3\n");
            break;
        case '?':
            printf("用法:./a.out [-a 123 -b 456 -c 789 -v] \n");
            break;   
        default:
            break;
        }
    }
    return 0;
}

[wbyq@wbyq linux_c]$ ./a.out 
[wbyq@wbyq linux_c]$ ./a.out -a 1234
当前的选项形参:a,值:1234
[wbyq@wbyq linux_c]$ ./a.out -a123 1234
当前的选项形参:a,值:1234
[wbyq@wbyq linux_c]$ ./a.out --a123 1234
当前的选项形参:a,值:1234
目录
相关文章
|
29天前
|
域名解析 网络协议 安全
在Linux中,想在命令行下访问某个网站,并且该网站域名还没有解析,如何做?
在Linux中,想在命令行下访问某个网站,并且该网站域名还没有解析,如何做?
|
29天前
|
网络协议 Linux Docker
在Linux中,如何指定dns服务器,来解析某个域名?
在Linux中,如何指定dns服务器,来解析某个域名?
|
20天前
|
图形学 开发者 存储
超越基础教程:深度拆解Unity地形编辑器的每一个隐藏角落,让你的游戏世界既浩瀚无垠又细节满满——从新手到高手的全面技巧升级秘籍
【8月更文挑战第31天】Unity地形编辑器是游戏开发中的重要工具,可快速创建复杂多变的游戏环境。本文通过比较不同地形编辑技术,详细介绍如何利用其功能构建广阔且精细的游戏世界,并提供具体示例代码,展示从基础地形绘制到植被与纹理添加的全过程。通过学习这些技巧,开发者能显著提升游戏画面质量和玩家体验。
52 3
|
21天前
|
安全 Linux 开发工具
探索Linux操作系统:从命令行到脚本编程
【8月更文挑战第31天】在这篇文章中,我们将一起潜入Linux操作系统的海洋,从最基础的命令行操作开始,逐步深入到编写实用的脚本。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和实用技能。我们将通过实际代码示例,展示如何在日常工作中利用Linux的强大功能来简化任务和提高效率。准备好了吗?让我们一起开启这段旅程,探索Linux的奥秘吧!
|
20天前
|
Linux
探索Linux操作系统:命令行与脚本编程基础
【8月更文挑战第31天】在这篇文章中,我们将一起踏上一段旅程,深入探索Linux操作系统的奥秘。通过学习命令行的使用和编写简单的脚本,你将能够更高效地与你的计算机进行交流。无论你是新手还是有经验的用户,本文都将为你打开一扇通往Linux世界的大门。准备好了吗?让我们开始吧!
|
22天前
|
运维 监控 Linux
深入理解Linux系统运维:命令行与脚本的奥秘
【8月更文挑战第30天】在Linux的世界里,命令行是运维人员的灵魂之窗。掌握命令行,就像握住了一把钥匙,能开启系统管理的宝藏箱。本文将带你走进Linux的命令行世界,通过实际代码示例,解锁那些高效管理和维护系统的秘籍。你将学到不仅仅是命令本身,更是如何将这些命令编织成强大的脚本,让日常的运维工作变得游刃有余。准备好跟随我的步伐,一起深入探索Linux命令行与脚本的奥秘吧!
|
23天前
|
Linux
Linux命令行文档查看cat、less、more、head、tail和图片查看
Linux命令行文档查看cat、less、more、head、tail和图片查看
41 0
|
29天前
|
网络协议 Linux
在Linux中,如何改IP、主机名、DNS?
在Linux中,如何改IP、主机名、DNS?
|
29天前
|
域名解析 网络协议 Linux
在Linux中,我们都知道,dns采用了tcp协议,又采用了udp协议,什么时候采用tcp协议?什么 时候采用udp协议?为什么要这么设计?
在Linux中,我们都知道,dns采用了tcp协议,又采用了udp协议,什么时候采用tcp协议?什么 时候采用udp协议?为什么要这么设计?
|
29天前
|
缓存 网络协议 Linux
在Linux中,当用户在浏览器当中输入⼀个网站,计算机对dns解释经过那些流程?
在Linux中,当用户在浏览器当中输入⼀个网站,计算机对dns解释经过那些流程?

热门文章

最新文章