首页 > 解决方案 > 如何从父进程读取标准输入?

问题描述

我需要编写启动 bash 并检查用户输入的程序。例如,如果我写“io”,程序必须打印到标准输出“LOL”。不幸的是,我的代码不起作用。

#include <iostream>
#include <thread>
#include <cstdlib>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <fstream>

int         main(int ac, char **av)
{
    ssize_t count;

    switch(fork())
    {
        case -1 :
        {
            std::cout << strerror(errno) << std::endl;
            break;
        }
        case 0 : // child
        {
            char    curr = 0, prev = 0;

            while ((count = read(0, (void*)&curr, 1)))
            {
                if (count == -1)
                {
                    std::cout << strerror(errno) << std::endl;
                    return 1;
                }
                if (prev == 'i' && curr == 'o')
                {
                    std::cout << "LOL" << std::endl;
                }
                prev = curr;
            }
            break;
        }
        default: // parent
        {
            char *const *bashArgs = {NULL};

            execvp("bash", bashArgs);
            break;
        }
    }
    return 0;
}

上面的代码只是无限地读取我在 konsole 上写的内容,然后失败并出现“bash:我写的狗屎:找不到命令”。然后无限阅读停止,我在 bash 会话中。然后我只是通过 Ctrl+D 退出这个会话到我的默认 bash 会话。

我也尝试通过 pipe() 和 dup2() 来做到这一点。下面的代码只是启动会话并且什么都不做。

#include <iostream>
#include <thread>
#include <cstdlib>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <fstream>

int         main(int ac, char **av)
{
    ssize_t count;
    int     fd[2];

    if (pipe(fd) == -1)
        std::cout << strerror(errno) << std::endl;

    switch(fork())
    {
        case -1 :
        {
            std::cout << strerror(errno) << std::endl;
            break;
        }
        case 0 : // child
        {
            char    curr = 0, prev = 0;

            while ((count = read(fd[0], (void*)&curr, 1)))
            {
                if (count == -1)
                {
                    std::cout << strerror(errno) << std::endl;
                    return 1;
                }
                if (prev == 'i' && curr == 'o')
                {
                    std::cout << "LOL" << std::endl;
                }
                prev = curr;
            }
            break;
        }
        default: // parent
        {
            char *const *bashArgs = {NULL};

            dup2(STDIN_FILENO, fd[1]);

            execvp("bash", bashArgs);
            break;
        }
    }
    return 0;
}

标签: c++bash

解决方案


推荐阅读