执行输入重定向并捕获命令输出(自定义类 shell 程序)

发布于 2025-01-21 01:33:30 字数 1422 浏览 2 评论 0原文

我正在编写一个自定义 shell,尝试像标准 shell 一样添加对输入、输出重定向和管道的支持。我陷入了无法进行输入重定向的境地,但输出重定向工作正常。我的实现是这样的(仅相关部分),您可以假设(字符串)输入非空

void execute() {
... // stuff before execution and initialization of variables
int *fds;
std::string content;
std::string input = readFromAFile(in_file); // for input redirection

for (int i = 0; i < commands.size(); i++) {
        fds = subprocess(commands[i]);
        dprintf(fds[1], "%s", input.data()); // write to write-end of pipe
        close(fds[1]);
        content += readFromFD(fds[0]); // read from read-end of pipe
        close(fds[0]);
    }
... // stuff after execution
}


int *subprocess(std::string &cmd) {
    std::string s;
    int *fds = new int[2];
    pipe(fds);
    pid_t pid = fork();
    if (pid == -1) {
        std::cerr << "Fork failed.";
    }
    if (pid == 0) {
        dup2(fds[1], STDOUT_FILENO);
        dup2(fds[0], STDIN_FILENO);
        close(fds[1]);
        close(fds[0]);
        system(cmd.data());
        exit(0); // child terminates
    }
    return fds;
}

我的想法是子进程返回一个管道(fd_in,fd_out)并且父级可以写入 write-之后从 read-end 开始读取。但是,当我尝试输入重定向时,例如 sort <在.txt 中,程序只是挂起。我认为存在死锁,因为一个等待另一个写入,另一个等待另一个读取,但是,在父级写入写入端后,它会关闭,然后从读取端读取。我该如何看待这种情况?

当我做了一些搜索时,我看到了这个答案,我最初的想法是相似的,除了在答案中提到创建两个管道。我不太明白这部分。为什么我们需要两个独立的管道?

I'm writing a custom shell where I try to add support for input, output redirections and pipes just like standard shell. I stuck at point where I cannot do input redirection, but output redirection is perfectly working. My implementation is something like this (only related part), you can assume that (string) input is non-empty

void execute() {
... // stuff before execution and initialization of variables
int *fds;
std::string content;
std::string input = readFromAFile(in_file); // for input redirection

for (int i = 0; i < commands.size(); i++) {
        fds = subprocess(commands[i]);
        dprintf(fds[1], "%s", input.data()); // write to write-end of pipe
        close(fds[1]);
        content += readFromFD(fds[0]); // read from read-end of pipe
        close(fds[0]);
    }
... // stuff after execution
}


int *subprocess(std::string &cmd) {
    std::string s;
    int *fds = new int[2];
    pipe(fds);
    pid_t pid = fork();
    if (pid == -1) {
        std::cerr << "Fork failed.";
    }
    if (pid == 0) {
        dup2(fds[1], STDOUT_FILENO);
        dup2(fds[0], STDIN_FILENO);
        close(fds[1]);
        close(fds[0]);
        system(cmd.data());
        exit(0); // child terminates
    }
    return fds;
}

My thought is subprocess returns a pipe (fd_in, fd_out) and parent can write to write-end and read-from read-end afterwards. However when I try an input redirection something like sort < in.txt, the program just hangs. I think there is a deadlock because one waiting other to write, and other one to read, however, after parent writes to write-end it closes, and then read from read-end. How should I consider this case ?

When I did a bit of searching, I saw this answer, which my original thinking was similar except that in the answer it mentions creating two pipes. I did not quite understand this part. Why do we need two separate pipes ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文