Linux环境C语言子进程执行命令与shell脚本问题求助
Linux C语言执行shell脚本并捕获输出实现方案
核心思路
原来的第一部分代码是直接执行用户传入的单个命令,要支持shell脚本语法,无需自行实现shell解析逻辑,直接调用系统/bin/sh解释器执行传入的脚本文件即可,shell会自动处理管道、重定向、通配符等语法规则,执行逻辑和原有父进程捕获输出的逻辑完全兼容。
代码修改说明
仅需要修改子进程中execvp的调用参数即可,其余管道创建、父子进程逻辑、父进程读输出打印的逻辑都可以复用原有代码:
- 子进程执行的程序改为
/bin/sh - 给sh传入目标脚本路径作为参数,让sh直接执行目标脚本文件
修改后完整代码
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main(int argc,char * argv[]){ // 入参校验,必须传入脚本文件路径 if(argc < 2){ printf("请传入shell脚本文件路径作为参数\n"); return -1; } // 创建管道 int descripteur[2]; if(pipe(descripteur) != 0){ return -1; } // 创建子进程 pid_t pid_fils; pid_fils = fork(); if(pid_fils ==-1){ return -1; } // 子进程逻辑 if (pid_fils == 0){ close(descripteur[0]); // 把标准输出和标准错误都重定向到管道写端 if(dup2(descripteur[1],1) == -1){ printf("Erreur\n"); return -1; }; if(dup2(descripteur[1],2) == -1){ printf("Erreur\n"); return -1; }; close(descripteur[1]); // 调用/bin/sh执行传入的脚本文件 char * exec_args[] = {"/bin/sh", argv[1], NULL}; if(execvp("/bin/sh", exec_args) == -1){ printf("Erreur\n"); return -1; }; } // 父进程逻辑 else{ char bufferHelper[256]; close(descripteur[1]); int nbBit; while((nbBit = read(descripteur[0], bufferHelper, sizeof(bufferHelper))) !=0){ write( 1, bufferHelper, nbBit); } // 等待子进程退出回收资源,避免僵尸进程 wait(NULL); } return 0; }
注意事项
- 如果传入的脚本没有可执行权限,可以把exec参数修改为
char * exec_args[] = {"/bin/sh", "-c", argv[1], NULL};,仍可正常执行 - 该实现自动兼容所有sh标准语法,包括管道、重定向、通配符、命令组合等,不需要额外开发解析逻辑
- 脚本内所有命令的输出都会被管道捕获,最终由父进程统一打印,和第一部分的输出表现完全一致
内容的提问来源于stack exchange,提问作者VéH
相关产品推荐
相关产品推荐

