如何启动应用程序并通过stdout和stderr捕获输出?
我正在编写一个自动构建系统,我需要捕获输出以进行分析.我想更新svn repo并获取修订号,这样我就可以在autobuild/revNumber /中移动文件,如果成功的话.我还想使用make构建并将编译文本上传到我的服务器,以便每个人都能看到失败构建的警告和错误.
我找不到该system()
功能,但我CreateProcess()
在MSDN上找到了该功能.我能够启动我需要但我不知道如何捕获stderr和stdout.我注意到该过程是单独启动的,除非我设置断点并保持我的应用程序退出,然后它将保留我的应用程序控制台窗口中的所有文本.我还想等到所有进程完成后再扫描它生成的数据,以执行我需要的任何其他操作.我该怎么做?
在真正的炮弹中(意思是,不是海贝壳 - 我的意思是,不是在C壳牌或其衍生物中),那么:
program arg1 arg2 >/tmp/log.file 2>&1
这将使用给定的参数运行程序,并将stdout重定向到/tmp/log.file; 符号(象形文字)' 2>&1
'最后将stderr(文件描述符2)发送到stdout(文件描述符1)所在的相同位置.请注意,操作顺序很重要; 如果你反转它们,那么标准错误将转到标准输出的去向,然后标准输出(但不是标准错误)将被重定向到文件.
显示的文件名选择很糟糕 - 原因很多 - 您应该允许用户选择目录,并且可能应该在文件名中包含进程ID或时间戳.
LOG=${TMPDIR:-/tmp}/log.$$.$(date +%Y%m%d-%H%M%S) program arg1 arg2 >$LOG 2>&1
在C++中,您可以使用该system()
函数(继承自C)来运行进程.如果您需要知道C++程序中的文件名(似是而非),那么在程序中生成名称(strftime()
是您的朋友)并使用该文件名创建命令字符串.(严格来说,你还需要getenv()
获得$ TMPDIR和POSIX函数getpid()
来获取进程ID,然后你可以模拟双线shell脚本(虽然使用的PID将是C++程序,而不是已启动的shell).
你可以改用POSIX popen()
函数; 你必须2>&1
在你创建的命令字符串中包含' '符号,以便将标准错误发送到与标准输出相同的位置,但是你不需要临时文件:
FILE *pp = popen("program arg1 arg2 2>&1", "r");
然后,您可以读取文件流.我不确定是否有一种将C文件流映射到C++ istream的简洁方法; 可能有.