繁体   English   中英

使用boost :: process读取cout并将其写入cin

[英]Read cout and write to cin of a process with boost::process

我正在尝试生成一个shell并读取stdout和stderr,并让用户通过写入stdin来运行命令。 我似乎无法从stdout或stderr读取内容,并且向stdin写入内容显然也无济于事。

如果我不尝试重定向任何stdin,stdout或stderr,它将生成一个正常的shell,就像我期望的那样。 但是,重定向它们只会使一切消失。 >>只是神秘地挂起。 我从孩子的标准输出中取出,然后将其放回实际的标准输出中,因此我希望至少可以显示类似用户名的内容,但是就像我说的那样,它只是阻塞了,因为缓冲区中肯定没有任何内容。

boost::process::child shell;
boost::process::opstream instream;
boost::process::ipstream errstream;
boost::process::ipstream outstream;

void console_out_read()
{
    char ch;
    do
    {
        outstream >> ch;
        std::cout << ch;
    }
    while(true);
}

void console_err_read()
{
    char ch;
    do
    {
        errstream >> ch;
        std::cerr << ch;
    }
    while(true);
}

void console_in_write()
{
    int ch;
    do
    {
        std::cin >> ch;
        instream << ch;
    }
    while(true);
}

int main()
{
    std::error_code ec;

    shell = boost::process::child("bash",
        boost::process::std_out > outstream,
        boost::process::std_err > errstream,
        boost::process::std_in < instream,
        ec);

    boost::thread cro(console_out_read);
    boost::thread cre(console_err_read);
    boost::thread cwi(console_in_write);
    shell.wait();
    return 0;
}

您发布的代码存在几个问题。

首先,在console_in_write您将ch声明为int而不是char 这意味着std::cin将只接受看起来像数字的东西。 如果您输入数字以外的内容,这将导致std::cin进入错误状态。

其次,即使将ch更改为charstd::cin >> ch也将永远不会读取换行符,因为格式化的输入操作会丢弃空格。 解决此问题的最简单方法是使用std::getline逐行读取而不是逐字符读取,并在读取的每一行之后仅写入换行符。

第三,boost的管道流被完全缓冲。 这意味着您需要在编写换行符后刷新流,以便将数据发送到子进程。 否则,您将键入命令,并且不会发生任何事情,因为数据仅位于流的缓冲区中。

第四,必须将std::thread超出范围才能进行joindetach 由于您当前不使用I / O线程,因此子进程退出后,父进程将崩溃。

将所有这些放在一起,我期望一个最小的示例看起来像这样:

boost::process::child shell;
boost::process::opstream instream;
boost::process::ipstream errstream;
boost::process::ipstream outstream;

void console_out_read()
{
    std::string line;
    while (std::getline(outstream, line))
    {
        std::cout << line << '\n';
    }
}

void console_err_read()
{
    std::string line;
    while (std::getline(errstream, line))
    {
        std::cout << line << '\n';
    }
}

void console_in_write()
{
    std::string line;
    while (std::getline(std::cin, line))
    {
        instream << line << std::endl;
        if (line == "exit") return;
    }
}

int main()
{
    std::error_code ec;

    shell = boost::process::child("bash",
        boost::process::std_out > outstream,
        boost::process::std_err > errstream,
        boost::process::std_in < instream,
        ec);

    std::thread cro(console_out_read);
    std::thread cre(console_err_read);
    std::thread cwi(console_in_write);
    shell.wait();
    cro.join();
    cre.join();
    cwi.join();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM