如何在进程运行时捕获标准输出并打印到控制台和文件(C Boost.Process)

如何在进程运行时捕获标准输出并打印到控制台和文件(C Boost.Process),第1张

概述我正在开发一个使用Boost的C Process库启动子进程的应用程序 ( http://www.highscore.de/boost/process0.5) 并使用以下代码将标准从该进程重定向到文件:     boost :: process :: initializers :: bind_stdout(boost :: iostreams :: file_descriptor_sink到这里) 我正在开发一个使用Boost的C Process库启动子进程的应用程序
( http://www.highscore.de/boost/process0.5)
并使用以下代码将标准从该进程重定向到文件:
    boost :: process :: initializers :: bind_stdout(boost :: iostreams :: file_descriptor_sink到这里)

上述解决方案和代码运行良好.

但是,现在,我需要能够将子进程的标准输出到文件和控制台.

我发现下面的代码似乎应该做的工作:

#include <boost/process.hpp>#include <boost/iostreams/device/file_descriptor.hpp>#include <boost/iostreams/stream.hpp>#include <iostream>using namespace boost::process;using namespace boost::process::initializers;using namespace boost::iostreams;int main(){    boost::process::pipe p = create_pipe();    {        file_descriptor_sink sink(p.sink,close_handle);        execute(            run_exe("/bin/echo"),set_cmd_line("echo hello"),bind_stdout(sink)        );    }    file_descriptor_source source(p.source,close_handle);    stream<file_descriptor_source> is(source);    std::string s;    while (std::getline(is,s))    {            std::cout << s << std::endl;            //will write line by line to file here    }}

我已经尝试运行上面的代码,事实上我能够将输出打印到控制台和文件.
但是上面的代码存在一个主要问题(至少在我的情况下),
while循环(while(std :: getline(is,s)))仅在调用的进程退出后启动,这意味着在进程完成后立即打印在进程运行期间累积的所有输出.

现在,
我需要的是能够在运行期间从调用的进程获取输出,并在它到来时将其打印到控制台和文件(而不是仅在结束时).

(由于我启动的进程不受我的控制,甚至可能需要几分钟才能运行,目前屏幕控制台只是空的,直到进程退出).

我已经找了很多网站试图找到这个解决方案,并且在代码中玩了很多,但我似乎无法解决这个问题.

如何实现这一目标? (甚至可以使用Boost.Process吗?)
如何在运行时期间使用std从子进程填充该字符串/流,而不是只在它完成时?

解决方法 原则上它应该按照您的要求工作.

也许你需要冲洗. (尝试使用std :: unitbuf).

或者,您可能在windows上,它不支持异步管道.文档描述了create_async_pipe函数:

bp::pipe create_async_pipe(){#if defined(BOOST_windows_API)    std::string name = "\\.\pipe\boost_process_async_io";    HANDLE handle1 = ::CreatenamedPipeA(name.c_str(),PIPE_ACCESS_INBOUND |        file_FLAG_OVERLAPPED,1,8192,NulL);    HANDLE handle2 = ::CreatefileA(name.c_str(),GENERIC_WRITE,NulL,OPEN_EXISTING,file_FLAG_OVERLAPPED,NulL);    return make_pipe(handle1,handle2);#elif defined(BOOST_POSIX_API)    return create_pipe();#endif}

所以,这是一个结合了它的版本,完整的tee设备:

#include <boost/process.hpp>#include <boost/iostreams/device/file_descriptor.hpp>#include <boost/iostreams/stream.hpp>#include <boost/iostreams/tee.hpp>#include <boost/iostreams/filtering_stream.hpp>#include <iostream>#include <fstream>namespace bp = boost::process;namespace io = boost::iostreams;using namespace bp;using namespace bp::initializers;bp::pipe create_async_pipe(){#if defined(BOOST_windows_API)    std::string name = "\\.\pipe\boost_process_async_io";    HANDLE handle1 = ::CreatenamedPipeA(name.c_str(),handle2);#elif defined(BOOST_POSIX_API)    return create_pipe();#endif}int main(){    bp::pipe p = create_async_pipe();    {        io::file_descriptor_sink sink(p.sink,io::close_handle);        execute(            run_exe("/bin/sh"),set_cmd_line("sh -c \"echo started; sleep 3 && date\""),bind_stdout(sink)        );    }    io::file_descriptor_source source(p.source,io::close_handle);    io::stream<io::file_descriptor_source> is(source);    std::cout << "Process is running,let's wait before printing\n";    system("sleep 1");    std::ofstream ofile("test.log");    io::filtering_ostream filt(io::tee(std::cout << std::unitbuf,ofile << std::unitbuf));    std::string s;    while (std::getline(is,s))        filt << s << "\n";}

已经选择了这些命令,您可以验证它是否以异步方式工作.

如果您想要“真正的”异步,您也可以使用Boost Asio,有关详细信息,请参阅文档:http://www.highscore.de/boost/process0.5/boost_process/tutorial.html#boost_process.tutorial.asynchronous_i_o

总结

以上是内存溢出为你收集整理的如何在进程运行时捕获标准输出并打印到控制台和文件(C /Boost.Process)全部内容,希望文章能够帮你解决如何在进程运行时捕获标准输出并打印到控制台和文件(C /Boost.Process)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1227422.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存