C程序执行shell脚本如何捕获echo输出且不打印到终端
解决方案
你当前使用的system()函数仅能获取脚本的退出状态码,无法捕获脚本的标准输出内容,同时脚本的默认输出会直接打印到终端,不符合你的需求。可以使用POSIX标准的popen()函数实现需求:该函数会创建管道连接子进程的标准输入/输出,以读模式启动进程时可以直接读取子进程的所有标准输出,且输出不会打印到终端。
修改后的完整代码
#include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <string.h> const char *fileName = "./tmp_script"; #define READ_BUF_SIZE 1024 // 可根据实际输出内容大小调整 int main() { FILE *log_f; char valueRead[READ_BUF_SIZE] = {0}; // 存储读取到的输出内容 // 创建脚本文件,使用w模式覆盖写入,避免历史残留内容影响执行结果 log_f = fopen(fileName, "w"); if (log_f == NULL) { return -1; } fputs("#!/bin/bash\n\n\n", log_f); fputs("echo something\n", log_f); // 不要设置0777权限,风险极高,改为仅当前用户可读写执行 chmod(fileName, 0700); fclose(log_f); // 用popen读模式启动脚本,捕获标准输出 FILE *script_fp = popen(fileName, "r"); if (script_fp == NULL) { remove(fileName); return -1; } // 读取脚本输出内容 fread(valueRead, 1, READ_BUF_SIZE - 1, script_fp); // 去掉末尾的换行符(echo命令默认会追加换行) valueRead[strcspn(valueRead, "\n")] = '\0'; // 关闭popen句柄,返回值是脚本的退出状态码,可自行判断执行是否成功 int exec_status = pclose(script_fp); if (exec_status == -1) { remove(fileName); return -1; } // 此处即可用valueRead和目标常量做对比 printf("读取到的脚本输出:%s\n", valueRead); remove(fileName); return 0; }
额外优化建议
- 如果需要同时捕获脚本的错误输出,可将popen的第一个参数改为
"./tmp_script 2>&1",会把stderr重定向到stdout一起捕获 - 临时脚本路径建议使用
mkstemp生成随机文件名,避免路径冲突、被其他进程篡改的风险 - 如果输出内容长度不确定,可以循环调用
fread动态扩容存储缓冲区,避免内容截断
内容的提问来源于stack exchange,提问作者ad_valle
相关产品推荐
相关产品推荐

