C++ VSCode Ubuntu 终端拦截命令行响应

问题描述 投票:0回答:1

我在 VSCode 中有一个 Linux C++ 程序,我正在尝试调试它。我正在使用 Boost process::ipstream 发送像“ip -a”这样的命令行命令,然后尝试使用 std::getLine() 读取 iostream 并处理响应,该响应是所有网络接口的多行列表信息。我尝试了很多不同的方法,但无论我做什么,只要我发出命令,我就会在 VSCode 终端中看到响应,而我的编码阅读器逻辑什么也得不到。我已经阅读了 VSCode 终端设置,以了解如何不解析响应,但发现没有在 VSCode 的 settings.json 文件中起作用的设置。

我觉得核心问题是 VSCode 窃取终端中的响应,因此我无法在代码中获取它们。有没有人见过这样的事情以及如何禁用终端解析对我发送的 CLI 命令的响应?

郑重声明,我真正想做的是从我的 C++ 代码中运行 speedtest cli 应用程序并解析那里的响应,但我想我应该先尝试一些简单的东西,所以只是尝试能够解析来自“ip -a”命令。

我知道,代码很好。这是我最近想做的事情(绝望中我尝试了 ChatGPT 中的一些东西):

    io_service io;
    ip::tcp::resolver resolver(io);
    boost::process::ipstream output;

    // Set up the command
    std::string command = "ip -a";

    // Set a timeout (in seconds) for the operation
    int timeout = 5;

    // Start the child process to run the ping command
    boost::process::child c(command, boost::process::std_out > output, io);

// As soon as I step over the above line I see the response in VSCode Terminal view

    // Wait for the process to exit or timeout
    if (c.wait_for(std::chrono::seconds(timeout)) == 0) {
        // Process completed within the timeout

        // Read and parse the output of the ping command
        std::string line;
        while (std::getline(output, line)) {
            // Parse and process the ping output here
            std::cout << "GLH: " << line << std::endl;
        }
    } else {
        // Process didn't complete within the timeout
// I hit this timeout every time
        std::cout << "Timeout occurred." << std::endl;
    }

谢谢

visual-studio-code c++11 boost getline
1个回答
0
投票

我无法重现该问题。首先,

ip -a
似乎是无效命令。有可能输出出现在终端中是因为是错误信息,所以转到
stderr

这是我的简化方法:

实时编译器资源管理器

#include <boost/asio.hpp>
#include <boost/process.hpp>
#include <iomanip>
#include <iostream>
using namespace std::chrono_literals;
namespace bp = boost::process;

int main() {
    boost::asio::io_context  io;
    std::future<std::string> output;

    bp::child c("ip a", bp::std_out > output, io);
    io.run_for(5s);

    std::istringstream iss(output.get());
    for (std::string line; std::getline(iss, line);) {
        std::cout << "GLH: " << quoted(line) << std::endl;
    }
}

打印:

GLH: "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000"
GLH: "    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00"
GLH: "    inet 127.0.0.1/8 scope host lo"
GLH: "       valid_lft forever preferred_lft forever"
GLH: "    inet6 ::1/128 scope host "
GLH: "       valid_lft forever preferred_lft forever"
GLH: "2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000"
GLH: "    link/ether 90:2b:34:37:2d:9a brd ff:ff:ff:ff:ff:ff"
GLH: "    inet 192.168.xx.xxx/24 brd 192.168.50.255 scope global dynamic noprefixroute enp4s0"
GLH: "       valid_lft 85841sec preferred_lft 85841sec"
GLH: "    inet6 fe80::def5:7afe:7fd8:fd8b/64 scope link noprefixroute "
GLH: "       valid_lft forever preferred_lft forever"
GLH: "3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default "
GLH: "    link/ether 02:42:92:1e:41:c3 brd ff:ff:ff:ff:ff:ff"
GLH: "    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0"
GLH: "       valid_lft forever preferred_lft forever"

我会考虑立即解析,例如:

// #define BOOST_SPIRIT_X3_DEBUG 1
#include <boost/asio.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/process.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iomanip>
#include <iostream>
using namespace std::chrono_literals;
namespace bp = boost::process;

namespace NIC {
    using boost::asio::ip::address_v4;

    struct Entry {
        std::string iface;
        address_v4  net;
        unsigned    mask_number;
    };
} // namespace NIC

BOOST_FUSION_ADAPT_STRUCT(NIC::Entry, iface, net, mask_number)

namespace NIC {

    std::vector<Entry> parse(std::string_view sv) {
        using namespace boost::spirit::x3;
        auto to_address = [](auto& ctx) {
            auto raw  = _attr(ctx);
            _val(ctx) = address_v4::from_string(std::string(raw.begin(), raw.end()));
        };

        auto cidr   = rule<void, address_v4>{"cidr"} //
                    = raw[+(digit | '.')][to_address];
        auto ignore = omit[*(char_ - eol) % (eol >> !(+digit | "    inet "))];
        auto entry = rule<void, Entry>{"entry"} =            //
            omit[+digit] >> ": " >> +alnum >> ": <"          //
            >> ignore                                        // skip irrelevant
            >> eol >> "    inet " >> cidr >> '/' >> uint_ >> //
            ignore;

        std::vector<Entry> entries;
        parse(sv.begin(), sv.end(), entry % eol, entries);
        return entries;
    }

} // namespace NIC

int main() {
    boost::asio::io_context  io;
    std::future<std::string> output;

    bp::child c("ip a", bp::std_out > output, io);
    io.run_for(5s);

    for (auto [iface, cidr, mask] : NIC::parse(output.get()))
        std::cout << "iface " << iface << " net " << cidr << " mask " << mask << "\n";
}

哪个打印:

© www.soinside.com 2019 - 2024. All rights reserved.