【问题标题】:How to run commandline/terminal utils with Boost.Process 0.5?如何使用 Boost.Process 0.5 运行命令行/终端工具?
【发布时间】:2012-10-07 00:36:23
【问题描述】:

我发现有一个新的Boost.Process 0.5,但我看不到如何在 Windows Linux 和 Mac 上执行 pingecho

我用简单的方法让它至少在 Windows 上工作:

#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/process.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/error_code.hpp>

namespace bp = boost::process;
namespace bpi = boost::process::initializers;
namespace bio = boost::iostreams;
int main()
{
    bp::pipe p = bp::create_pipe();
    {
        bio::file_descriptor_sink sink(p.sink, bio::close_handle);
        boost::filesystem::path p("C:/Windows/System32/cmd.exe");
        boost::system::error_code ec;
        bp::execute(
            bpi::run_exe(p),
            bpi::set_cmd_line(L"cmd /c echo --echo-stderr hello"),
            bpi::bind_stdout(sink),
            bpi::set_on_error(ec)
            );
    }

    bio::file_descriptor_source source(p.source, bio::close_handle);
    bio::stream<bio::file_descriptor_source> is(source);

    std::string s;
    is >> s;
    std::cout << s << std::endl;
    std::cin.get();
    return 0;
}

在 Windows 上可以正常工作,但是如何让它跨平台也可以在 Mac 和 Linux 上工作? (我很愚蠢,不知道如何编写一条适用于任何 Unix 终端(或至少适用于 Linux Bash 和 mac 默认终端)的路径)所以如何在 Windows 和 Unix 上使用 Boost.Process 0.5 运行命令行/终端实用程序像操作系统(最好不要每次都写到终端的路径,而只是写像echoping这样的应用程序及其参数)?

...在prevoius版本中找到相关代码:

    std::string exe; 
    std::vector<std::string> args; 

#if defined(BOOST_POSIX_API) 
    exe = "/bin/sh"; 
    args.push_back("sh"); 
    args.push_back("-c"); 
    args.push_back(command); 
#elif defined(BOOST_WINDOWS_API) 
    char sysdir[MAX_PATH]; 
    UINT size = ::GetSystemDirectoryA(sysdir, sizeof(sysdir)); 
    if (!size) 
        boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_shell: GetWindowsDirectory failed")); 
    BOOST_ASSERT(size < MAX_PATH); 

    exe = std::string(sysdir) + (sysdir[size - 1] != '\\' ? "\\cmd.exe" : "cmd.exe"); 
    args.push_back("cmd"); 
    args.push_back("/c"); 
    args.push_back(command); 
#endif 

【问题讨论】:

    标签: c++ boost process


    【解决方案1】:

    在 boost.process 0.5 下引入了 shell_path() API,所以下面的内容可能会让您着迷

    #if defined(BOOST_POSIX_API) 
        #define SHELL_COMMAND_PREFIX "-c"
    #elif defined(BOOST_WINDOWS_API) 
        #define SHELL_COMMAND_PREFIX "/c"
    #endif
    
    
    filesystem::path shellPath = process::shell_path();
    std::string cl = shell_path().string() + " " SHELL_COMMAND_PREFIX " ";
    cl += "ping 127.0.0.1";
    execute(  
            set_cmd_line(cl),
            throw_on_error()
    );
    

    如果你真的想隐藏#ifdef,我会继续编辑 boost 源以返回相关的命令前缀(添加新的 API),毕竟开源不是吗? :)。 您可以在 boost/process/windows/shell_path.hpp 和 boost/process/posix/shell_path.hpp 中找到要编辑的相关资源

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-17
      • 2019-12-22
      • 2018-12-28
      • 2012-01-27
      • 2022-01-12
      相关资源
      最近更新 更多