You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 19:06:01