如何通过argv传入以指定分隔符分隔的多条命令并执行
实现思路
- 第一步预处理命令行参数,遍历
argv收集所有命令的起始指针,遇到分隔符+就将当前位置设为NULL(满足execvp要求的参数数组以NULL结尾的规则),同时记录下一个命令的起始位置 - 第二步遍历收集到的命令起始指针列表,每个命令对应调用一次
fork(),子进程执行execvp启动对应命令 - 第三步父进程调用对应次数的
wait()等待所有子进程执行完成 - 兼容C89标准,所有变量声明放在块开头,依赖的头文件都是Solaris 5.10默认支持的标准头文件
原有代码存在两个小问题需要先修正:一是缺少
<stdlib.h>(exit()函数依赖)、<sys/wait.h>(wait()函数依赖)头文件;二是未处理未找到分隔符+的边界场景,可能出现未初始化变量访问问题。
完整实现代码
#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> int main (int argc, char* argv[]) { /* 最多支持256个命令,可按需调整上限 */ char** cmd_starts[256]; int cmd_count = 0; int i; /* 非法输入校验:没有传任何参数 */ if (argc < 2) { fprintf(stderr, "Usage: %s cmd1 [args...] + cmd2 [args...] [+ cmd3 [args...] ...]\n", argv[0]); return 1; } /* 第一步:收集所有命令的起始地址 */ cmd_starts[cmd_count++] = &argv[1]; for (i = 1; i < argc; i++) { if (strcmp("+", argv[i]) == 0) { argv[i] = NULL; /* 兼容处理连续+的非法场景 */ if (i + 1 < argc && strcmp("+", argv[i+1]) != 0) { cmd_starts[cmd_count++] = &argv[i+1]; } } } /* 第二步:为每个命令fork子进程执行 */ for (i = 0; i < cmd_count; i++) { pid_t pid = fork(); if (pid == 0) { /* 子进程:执行命令 */ execvp(cmd_starts[i][0], cmd_starts[i]); perror("execvp failed"); exit(1); } else if (pid < 0) { perror("fork failed"); exit(1); } } /* 第三步:等待所有子进程退出 */ for (i = 0; i < cmd_count; i++) { wait(NULL); } return 0; }
使用示例
编译后执行如下命令即可同时运行4条自定义命令:./a.out ps -lu myUsername + ls -la + pwd + echo "hello world"
完全兼容原有的双命令使用场景。
内容的提问来源于stack exchange,提问作者sosensio
相关产品推荐
相关产品推荐

