get_opt cmd args命令行参数问题
最近调试一个项目,某个流程是proga调用fork之后,在子进程里构造一些命令行参数,调用execv执行另一个程序progb。
遇到了一个坑,命令行参数怎么都获取不正确,子进程还可以调试,但调用execv之后只能靠各种打log了,
把构造的参数,手工在shell里粘贴,执行progb程序, 也正常。
调试了好长时间,百思不得其解,最后发现是个空格惹的祸!
测试代码如下:
#include <unistd.h> #include <stdio.h> #include <getopt.h> static char *execv_cmd_args[10]; static const char* short_options = (const char *)"a:h"; static const struct option long_options[] = { {"help", 0, NULL, 'h'}, {"aaa", 1, NULL, 'a'}, {NULL, 0, NULL, 0}, }; int main(int argc, char *argv[]) { int i, c; int pid; if(argc >=2){ printf("child process start, arg num=%d....", argc); while((c=getopt_long(argc, argv, short_options, long_options, NULL))!=-1){ switch(c){ case 'a': printf("a=%s", optarg); break; default: printf("unknown args: value=%d, optarg=%s", c, optarg); } } while(1) pause(); return 0; } pid = fork(); if(0 == pid){ execv_cmd_args[0] = "test_args"; execv_cmd_args[1] = "--aaa"; execv_cmd_args[2] = "1"; execv_cmd_args[7] = NULL; execv("./a.out", execv_cmd_args); }else{ while(1) pause(); } return 0; } |
比较好理解,不解释了,编译运行后,打印如下结果:
child process start, arg num=3.... a=1 |
与构造的execv_cmd_args参数是一致的,没问题。
我之前有错误的那版代码是这么写的:
#include <unistd.h> #include <stdio.h> #include <getopt.h> static char *execv_cmd_args[10]; static const char* short_options = (const char *)"a:h"; static const struct option long_options[] = { {"help", 0, NULL, 'h'}, {"aaa", 1, NULL, 'a'}, {NULL, 0, NULL, 0}, }; int main(int argc, char *argv[]) { int i, c; int pid; if(argc >=2){ printf("child process start, arg num=%d....", argc); while((c=getopt_long(argc, argv, short_options, long_options, NULL))!=-1){ switch(c){ case 'a': printf("a=%s", optarg); break; default: printf("unknown args: value=%d, optarg=%s", c, optarg); } } while(1) pause(); return 0; } pid = fork(); if(0 == pid){ execv_cmd_args[0] = "test_args"; execv_cmd_args[1] = "--aaa "; /* 注意, 后面有个空格 */ execv_cmd_args[2] = "1"; execv_cmd_args[7] = NULL; execv("./a.out", execv_cmd_args); }else{ while(1) pause(); } return 0; } |
注意,--aaa后面是有个空格的,再编译运行,就不对了:
test_args: unrecognized option '--aaa ' unknown args: value=63, optarg=(null) |
虽然空格在shell命令行里没严格要求,多几个无所谓,
但execv认为"--aaa"和"--aaa "可不是一个参数!!!
切记!!