Linux命令参数
通过一个例子来理解什么是Linux命令参数。以Linux中常用的删除命令“rm”为例,输入“rm --help”可以看到如下信息,其中红色框内的就是命令参数。经常使用Linux对命令参数应该是非常熟悉的。例如我们经常使用的删除命令“rm -rf filename”。如果我们自己开发Linux命令,用代码来解析命令参数呢?Linux的标准库函数为我们提供了相关的方法。
命令解析相关函数(基于Linux C)
getopt()函数只能处理短选项(如上图中的“-f”,“-i”等单个字符的选项称为短选项,“--verbose”,“--help”等选项称为长选项)。getopt_long()函数既能处理短选项也能处理长选项。getopt_only()函数与getopt_long()函数相同。
#include <unistd.h>
#include <getopt.h>
extern char *optarg;
extern int optind, opterr, optopt;
int getopt(int argc, char * const argv[], const char *optstring);
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longidx);
int getopt_long_only(int argc, char * const argv[], const char *optstring, const sturuct option *longopts, int longidx);
全局变量
关于几个全局变量的说明。
1. optarg:表示当前选项对应的参数值,如果没有参数,值为NULL。
2. optind:表示的是下一个将被处理到的参数在argv中的下标值。
3. opterr:如果opterr = 0,在getopt(),getopt_long()和getopt_long_only()函数遇到错误将不会输出错误信息到标准输出流。如果opterr != 0,向 屏幕输出错误。
4. optopt:表示没有被未标识的选项。
getopt()函数
#include <unistd.h>
int getopt(int argc, char * const argv[], const char *optstring);
1. argc, argv:这两个参数就是main()函数中的参数。
2. optstring:由短选项参数组成的字符串。短选项字符串形式可以是“abc:d::e”,说明如下。
(1). 只有一个字符,不带冒号:表示选项,不带参数,如“-a”。
(2). 一个字符,后面带一个冒号:表示该选项必须带参数,不带参数就会出错,如“-c argument”。
(3). 一个字符,后面带两个冒号:表示该选项带或者不带参数都可以,如“-d [argument]”。
3. getopt()返回值:正确返回短选项字符,错误返回-1.
getopt()实例
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#define BUFSZ 4096
static void log_msg(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
char buf[BUFSZ];
vsnprintf(buf, BUFSZ - 1, fmt, ap);
fputs(buf, stdout);
fflush(stdout);
va_end(ap);
}
int main(int argc, char *argv[])
{
if (argc == 1) {
log_msg("usage: command -t argument.");
exit(0);
}
int c;
while ((c = getopt(argc, argv, "ab:c::")) != -1) {
switch (c) {
case 'a':
log_msg("-a option is received.");
break;
case 'b':
log_msg("-b option is received. its argument = %s.", argv[optind - 1]);
break;
case 'c':
log_msg("-b option is received. its argument = %s.", argv[optind]);
break;
default:
break;
}
}
exit(0);
}
getopt_long()函数
#include <unistd.h>
#include <getopt.h>
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option long_opts, int longidx);
1. argc,argv:main()函数的入参。
2. optstring:短选项字符串,与getopt()函数中的optstring参数相同。
3. long_opts:长选项参数结构体数组。
4. longidx:长选项结构体数组下标。
5. 返回值:参考struct option结构体说明。
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
name:表示长选项的名称。
has_arg:表示长选项后面是否带有参数。取值如下。
no_argument(或者0):选项后面不带参数,输入格式为“--option”,如“--help”。
required_argument(或者1):选项后面必须带参数,输入格式为“--option arg”或者“--option=arg”,如“--file FILE”或者“--file=FILE”。
optional_argument(或者2):选项后面可选择性的带参数,如果带参数,输入格式为“--option=arg”。
flag:该值可以为NULL或者非NULL。
NULL:当选中该长选项时,getopt_long()的返回值为val。
非NULL:当选中该长选项时,getopt_long()的返回值为0,并将flag指向val。
val:当flag为NULL时,指定getopt_long()函数的返回值。当flag非NULL时,flag指向val。
长选项实例
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <getopt.h>
#include <string.h>
#define BUFSZ 4096
static void log_msg(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
char buf[BUFSZ];
vsnprintf(buf, BUFSZ - 1, fmt, ap);
strcat(buf, "\n");
fputs(buf, stdout);
fflush(stdout);
va_end(ap);
}
int main(int argc, char *argv[])
{
struct option long_opts[] = {
{ "add", required_argument, NULL, 1 },
{ "append", no_argument, NULL, 2 },
{ "create", optional_argument, 3 }
};
int c;
int optidx = 0;
while ((c = getopt_long(argc, argv, NULL, long_opts, &optidx)) != -1) {
switch (c) {
case 1:
log_msg("--add option with argument %s", optarg);
break;
case 2:
log_msg("--append option with no argument.");
break;
case 3:
if (optarg) {
log_msg("--create option with argument %s", optarg);
} else {
log_msg("--create option with no argument.");
}
break;
default:
break;
}
}
exit(0);
}