macOS下C语言popen()管道无法获取命令输出问题咨询
问题原因及解决方案
错误信息未进入管道的原因
popen() 默认仅捕获目标命令的标准输出(stdout),而你看到的 sh: vcpkg: command not found 是启动的shell进程的**标准错误(stderr)**输出。这条错误信息没有被重定向到你创建的管道,而是直接继承了父进程(你的程序)的stderr输出流,也就是IDE关联的终端,所以直接打印了出来。
当你调用 popen("vcpkg", "r") 时,底层会启动OS X默认的sh shell去执行vcpkg命令,shell找不到该命令时,会将错误信息输出到自身的stderr,而这个stderr并没有被管道捕获。
让错误信息进入管道的解决方法
通过shell重定向语法,将stderr的内容重定向到stdout,这样所有输出都会通过管道返回给你的程序。修改popen的命令参数即可:
pipe = popen("vcpkg 2>&1", "r");
其中2>&1是shell的重定向规则,代表把文件描述符2(stderr)的输出重定向到文件描述符1(stdout),这样错误信息就会和正常输出一起进入管道。
额外优化点
你当前用!feof(pipe)作为循环判断条件存在逻辑问题,会导致最后一次读取时打印出EOF对应的字符(即你看到的\377)。建议改为直接判断fgetc的返回值:
int c; while ((c = fgetc(pipe)) != EOF) { fprintf(stdout, "Character read from the pipe is %c.\r\n", (char)c); }
因为feof只有在读取到EOF之后才会返回真,原逻辑会在fgetc返回EOF后仍执行一次循环体,导致错误打印EOF字符。
内容的提问来源于stack exchange,提问作者user1322654
相关产品推荐
相关产品推荐

