具有execv和输入重定向的C ++流水线命令 [英] c++ pipelining commands with execv and input redirection

查看:234
本文介绍了具有execv和输入重定向的C ++流水线命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图编写一个处理内部和外部命令的外壳程序.我一次可以获取内部命令和一个外部命令.

Trying to write a shell that processes internal and external commands. I can get the internal commands and one external at a time.

我的问题是如何让这样的命令运行:"ls -l | grep lib | wc -l"

My question is how to get a command like this to run: "ls -l | grep lib | wc -l"

我正在使用fork(),并通过char * []中的execv()传递外部命令.

I'm using a fork(), and passing external commands through execv() in a char*[].

关于如何进行此操作的任何想法?我假设使用pipe()之类的东西,但是我不确定.

Any thoughts on how to work this? I assume using pipe() or something, but I'm not sure.

问题的第二部分:如何处理I/O重定向?谁能指出我在某个有用的地方?

Second part of the question: how about dealing with i/o redirection? Can anyone point me to somewhere helpful?

编辑 到目前为止,@ Alex W是我的英雄.但是,由于我不熟悉pipe()和dup2()命令,因此我对每个调用和变量的用途都有些犹豫.

EDIT So far, @Alex W is my hero. However, since I'm new to the pipe() and dup2() commands, I'm a little hesitant on what each call and variable are for.

这是我处理单个外部命令的代码(示例="ls -l -a"):

Here's the code I have that handles a single external command (Example = "ls -l -a"):

    pid_t pid;
    pid = fork();
    if (pid < 0)
    {
        cout << "Fork failed." << endl;
    }
    else if (pid == 0)
    {
        execvp(exec_args[0], exec_args);   //exec_args is a char*[] where 
        _exit (EXIT_FAILURE);              //exec_args[0] contains "/bin/ls"
    }                                          //[1]="ls" and [2]="-l" [3]="-a"
    else
    {
        int status;
        waitpid(pid, &status, 0);
    }
    break;

推荐答案

您确实使用了pipe,并且在POSIX系统中,管道的工作方式与文件类似.您可以写入管道并从管道中读取数据,但是如果管道中没有任何内容,它将阻塞.在Unix系统调用上查找信息的最佳位置是系统调用的手册页.在Unix系统上,您可以在终端中输入man pipe.如果您无权访问Unix终端,则只需谷歌"man pipe".手册页的好处是,它们告诉您给定系统调用要包括哪些库.确保记住使用任何exec类型的系统调用时,您正在将一个全新的进程加载到该内存中,并且您正在执行的进程将停止在其轨道中.

You do use pipe and in POSIX systems a pipe works in a similar manner to a file. You can write to a pipe and read from a pipe, but if there is nothing in the pipe it blocks. The best place to find information on Unix system calls is the man page for the system call. On a Unix system you would type man pipe into a terminal. If you don't have access to a Unix terminal then just google "man pipe". The nice thing about the man pages is they tell you what libraries to include for the given system call. Make sure you remember that when using any exec type system call you are loading a completely new process into that memory and the process that you were executing will stop dead in its tracks.

要使用它,请执行以下操作:

To use it do something like this:

int main()
{
    int id[2];
    int fd[2];
    int fd2[2];
    int fd3[2];
    FILE file;
    int status;
    int sz = 0;
    char buff[1000];
    char buff2[1000];
    string launch[2];
    FILE *fp;

    launch[0] = "./anotherProgramToExecute";
    launch[1] = "./yetAnotherProgram";

    pipe(fd);
    pipe(fd2);
    pipe(fd3);

    for(int i = 0; i < 2; i++)
    {
        id[i] = fork();

        if (id[i] == -1) /* an error occurred */
        {
            perror("Fork failed.\n");
        }
        else if (id[i] == 0) /* this is the child process currently acting */
        {
            if(i == 0)
            {
                dup2(fd[1],1);
            }
            else if(i == 1)
            {
                dup2(fd2[0],0);
                dup2(fd3[1],1);
            }
            execlp(launch[i],launch[i], NULL);
        }
        else /* this is the parent process currently acting */
        {
            sz = read(fd[0], buff, 1000);
            buff[sz] = '\0';
            printf("buff = %s\n",buff);

            close(fd[0]);

            write(fd2[1],buff, 1000);

            read(fd3[0],buff2,1000);

            fp = fopen("bin.txt","w");
            if(fp == NULL)
                printf("Cannot open file.\n");
            else
            {
                fprintf(fp,buff2);
                fclose(fp);
            }

            //printf("Creation of Child Process #%d succeeded!\n",id[i]);
            while(waitpid(id[i], &status, WNOHANG) == 0)
                sleep(0.3);
            if (WIFEXITED(status))
            { 
                // successfully terminated children
            }
            else
            {
                perror("Child has not terminated correctly.\n");
            }
        }
    }
}

这篇关于具有execv和输入重定向的C ++流水线命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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