玩具外壳不正确 [英] Toy shell not piping correctly

查看:117
本文介绍了玩具外壳不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不会撒谎。这是一个家庭作业问题。然而,就我而言,点已经走了宝宝走了。现在,我只是寻找一个答案,因为我 - 我可能是疯了。

I'm not going to lie. This is a homework question. However, as far as I'm concerned, the points are gone baby gone. Right now, I'm just looking for an answer, because I -think- I might be insane.

这个程序的目标是执行命令 ps -A | grep(inputstring)| wc -l <​​/ code>的方式类似于shell如何做。所以,我产生的进程,让他们互相等待。最新的进程,大孙子 execlp(ps,ps, - A,NULL) ps -A 进程。在它之前 execlp ,我确保它的标准输出到管道输出。下一个进程是 wait() ing,并且已经设置好了,以便输入管道进入标准输入,标准输出到输出管道,它将执行grep,等等。

The goal of this program is to execute the command ps -A | grep (inputstring) | wc -l in a way similar to how the shell does it. So, I spawn the processes, and have them wait on each other. The newest process, the great-grandchild, execlp("ps","ps","-A",NULL) which replaces itself with the ps -A process. Before it execlp, I make sure its standard output is going to the pipe output. The next process in line is wait()ing, and already has itself set up so that the input pipe goes to standard in, and standard out goes to the output pipe, and it will execute grep, and so on.

我几乎肯定我已正确设置。然而...程序做。不。工作。

I'm almost positive I have it set up correctly. And yet... the program does. Not. Work.

#include <stdlib.h>
#include <iostream>
#include <string>

#define MAXLINE 1500
#define READ 0
#define WRITE 1

using namespace std;

int main( int argc, char** argv ) {
//* start of input block
if ( argc != 2 ) {
    cout << "Usage: ./a.out arg1" << endl;
    return 0;
}
string in = argv[1];
// end of input block */
int pipeA[2], pipeB[2], pid, stat;

// get our first set of pipes
if ( pipe(pipeA) < 0 ) {
    cerr << "Pipe error.\n";
    exit(-1);
}
if ( pipe(pipeB) < 0 ) {
    cerr << "Pipe error.\n";
    exit(-1);
}

// make the first fork
if ( (pid = fork() ) < 0 ) { cerr << "Fork error.\n"; exit(-1); }

if ( pid > 0 ) {    // parent case
    wait(&stat);
} else {            // child case
    if ( (pid = fork()) < 0 ) { cerr << "Fork Error\n"; exit(-1); }
    if ( pid > 0 ) {    // child
        wait(&stat);
        dup2(pipeA[READ],READ);
        execlp("wc","wc","-l",NULL);
    } else {    // grand-child
        if ( (pid = fork()) < 0 ) { cerr << "Fork Error\n"; exit(-1); }
        if ( pid > 0 ) {    // still grand-child
            wait(&stat);
            dup2(pipeB[READ],READ);  
            dup2(pipeA[WRITE],WRITE); 
            close(pipeB[READ]);
            execlp("grep","grep",in.c_str(),NULL);
        } else {    // great grand-child
            dup2(pipeB[WRITE],WRITE); // t now goes to pipeB[1]
            close(READ);
            close(pipeB[READ]);
            execlp("ps", "ps", "-A", NULL);
        }
    }
}
return 0;
}

编辑:更改为我的代码的双管道变体。 >

Changed to the two-pipe variant of my code.

推荐答案

我几乎肯定这是你想要做的。事先对错误的编码道歉。它在这里有点晚,我真的应该睡觉了:

I'm virtually certain this is what you're trying to do. Apologies in advance for the sloppy coding. its somewhat late here and I really should be sleeping right now:

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>

#define READ 0
#define WRITE 1

// ps -A | grep argv[1] | wc -l

int main( int argc, char** argv )
{
    //* start of input block
    if ( argc != 2 )
    {
        std::cout << "Usage: ./a.out arg1" << std::endl;
        return 0;
    }

    // make local copy of argument
    std::string in = argv[1];
    int fd1[2], fd2[2], pid;

    // allocate two pipe sets
    if (pipe(fd1) < 0 || pipe(fd2) < 0)
    {
        perror("Failed to create pipe.");
        return EXIT_FAILURE;
    }

    // launch first child process.
    if ((pid = fork()) < 0)
    {
        perror("Failed to fork child(1)");
        return EXIT_FAILURE;
    }

    if (pid == 0)
    {
        // wc -l process. 
        //  stdin  = fd2(read)
        close(fd1[READ]);
        close(fd1[WRITE]);
        close(fd2[WRITE]);
        dup2(fd2[READ],STDIN_FILENO);
        execlp("wc","wc","-l",NULL);
    }

    // fork again. this time for grep
    if ((pid = fork()) < 0)
    {
        perror("Failed to fork child(2)");
        return EXIT_FAILURE;
    }

    if (pid == 0)
    {
        // grep argv[1] process.
        //  stdin  = fd1(read)
        //  stdout = fd2(write)            
        close(fd1[WRITE]);
        close(fd2[READ]);
        dup2(fd2[WRITE], STDOUT_FILENO);
        dup2(fd1[READ], STDIN_FILENO);
        execlp("grep", "grep", in.c_str(), NULL);
    }

    //  fork once more. this time for ps -A
    if ((pid = fork()) < 0)
    {
        perror("Failed to fork child(3)");
        return EXIT_FAILURE;
    }

    if (pid == 0)
    {
        // ps -A process.
        //  stdout = fd1(write)
        close(fd2[WRITE]);
        close(fd2[READ]);
        close(fd1[READ]);
        dup2(fd1[WRITE], STDOUT_FILENO);
        execlp("ps", "ps", "-A", NULL);
    }

    int stat=0;
    wait(&stat);

    return EXIT_SUCCESS;
}



在我的系统上, ps -A 报告141行,其中41行中有 System 字样,通过运行 ps -A | grep系统| wc -l <​​/ code>。上述代码生成的输出完全相同。

On my system, ps -A reports 141 lines, of those 41 have the word System somewhere within, verified by simply running ps -A | grep System | wc -l. The above code generates precisely the same output.

希望它帮助你。

这篇关于玩具外壳不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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