管道,dup2和exec() [英] Pipes, dup2 and exec()

查看:79
本文介绍了管道,dup2和exec()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须编写一个可以运行管道的外壳.例如ls -l | wc -l之类的命令.我已经成功解析了用户给出的命令,如下所示:

I have to write a shell that can run pipes. For example commands like ls -l | wc -l". I have successfully parsed the command given by the user as below:

"ls" = firstcmd

"ls" = firstcmd

-l" = frsarg

"-l" = frsarg

"wc" = scmd

"wc" = scmd

-l" = secarg

"-l" = secarg

现在我必须使用两个fork,因为命令分别是两个和一个管道. 我为执行命令编写的代码块如下:

Now I have to use two forks since the commands are two and a pipe. The code block that I wrote to exec the command is the following:

pid_t pid;
int fd[2];

pipe(fd);
pid = fork();

if(pid==0)
{        
    dup2(fd[WRITE_END], STDOUT_FILENO);
    close(fd[READ_END]);
    execlp(firstcmd, firstcmd, frsarg, (char*) NULL);
}
else
{ 
    pid=fork();

    if(pid==0)
    {
        dup2(fd[READ_END], STDIN_FILENO);
        close(fd[WRITE_END]);
        execlp(scmd, scmd, secarg, (char*) NULL);
    }
}

因此,当我运行外壳程序并输入命令ls -l | wc -l(例如)时,执行程序的结果不会显示,但外壳程序将继续正常运行.

So when I run my shell and I enter the command ls -l | wc -l (for example) the result from the execs doesn't show up but the shell keeps running normally.

奇怪的是,仅当我使用"exit"或"^ C"终止外壳程序时,命令的结果才会显示.

The strange thing is that the result of the command shows only when I terminate my shell with "exit" or "^C".

该输出有什么问题?输入命令后,为什么它没有立即显示?

What is wrong with that output? Why doesn't it show up right after I enter the command?

推荐答案

您需要关闭父进程和子进程中的所有管道描述符(在子进程中进行复制之后).在您的代码中,主要问题是wc进程不会退出,因为仍然有写程序存在(因为父进程尚未关闭写端).更改如下所示.我还在父进程中添加了waitpid以等待wc进程.

You need to close all the pipe descriptors in both the parent process and the child process (after duplication in the child process). In your code the main issue is that, the wc process does not exit because there are still writers present (since the parent process has not closed the write end). Changes shown below. I have also added the waitpid in the parent process to wait for the wc process.

pid_t pid;
int fd[2];

pipe(fd);
pid = fork();

if(pid==0)
{
    dup2(fd[WRITE_END], STDOUT_FILENO);
    close(fd[READ_END]);
    close(fd[WRITE_END]);
    execlp(firstcmd, firstcmd, frsarg, (char*) NULL);
    fprintf(stderr, "Failed to execute '%s'\n", firstcmd);
    exit(1);
}
else
{ 
    pid=fork();

    if(pid==0)
    {
        dup2(fd[READ_END], STDIN_FILENO);
        close(fd[WRITE_END]);
        close(fd[READ_END]);
        execlp(scmd, scmd, secarg,(char*) NULL);
        fprintf(stderr, "Failed to execute '%s'\n", scmd);
        exit(1);
    }
    else
    {
        int status;
        close(fd[READ_END]);
        close(fd[WRITE_END]);
        waitpid(pid, &status, 0);
    }
}

这篇关于管道,dup2和exec()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆