在c ++中递归执行Linux管道命令

时间:2017-03-15 01:45:47

标签: c++ c linux recursion

我的实现使用递归来执行具有多个管道的命令,因此理论上我只需要2个管道。但是,在第二次迭代后,read()会阻止我的程序暂停。我只能执行" ls -la | cat -A" " ls -la |的一部分猫-A |猫-A | cat -A"但我的程序将停留在read()并永远不会退出。如果我注释掉导致此问题的读取,程序将结束并退出,但当然我没有输出。有谁知道为什么会这样?我也尝试过迭代实现,但是我得到了同样的错误。

char* buf[1000];
int recursion_fd[2];
int output_size;
auto pipe_recursion_fd = pipe(recursion_fd);


void execute_pipe(vector<vector<string>> commands)
{

    //PUT THE COMMAND INTO ARRAY TO CALL WITH EXEC
    char* args[] = {0,0,0,0,0,0,0,0,0,0};
    for(int i=0; i < commands.at(0).size();++i)
    {
        int size = commands.at(0).at(i).size() + 1;
        args[i] = new char[size];
        strcpy(args[i],commands.at(0).at(i).c_str()); 
    }

    //CREAT PIPE AND FORK
    int fd[2];
    pipe(fd);
    int pid = fork();

    //CHILD
    if(pid == 0)
    {
        dup2(recursion_fd[0],STDIN_FILENO);
        dup2(fd[1],STDOUT_FILENO);

        //dup(recursion_fd[0]);
        //dup(fd[1]);

        int exec_status = execvp(args[0],args);
        cout << "exec failed - not a valid command" << endl;
        exit(0);
    }

    //PARENT
    if(pid != 0)
    {
        waitpid(pid,NULL,WNOHANG);
        //close(fd[1]);

        //THIS IS THE RECURSION CONDITION, THE LAST ITERATTION SHOULD PRINT 0
        cout << "   num pipes " << num_pipes(commands) << endl;

        if(num_pipes(commands) > 0)
        {
            //THIS CAUSES HOLD
            output_size = read(fd[0],buf,sizeof(buf));

            printf("inside buf:: %s \n",buf); //PRINT TO TEST ITERATIONS
            write(recursion_fd[1],buf,output_size);
            commands.erase(commands.begin()); //erase completed command
            commands.erase(commands.begin()); //erase pipe
            execute_pipe(commands);
        }

        else
        {
            //THIS CAUSES HOLD
            output_size = read(fd[0],buf,sizeof(buf));

            return;
        }

    }

}

void test_execute_pipe()
{
    string command;
    cout << ":: ";
    getline(cin,command);
    vector<vector<string>> test = seperate_command(command);

    cout << "test size = " << test.size() << endl;
    for(int i=0; i < test.size(); ++i)
    {
        for(int c=0; c < test.at(i).size(); ++c)
        {
            cout << test.at(i).at(c) << "~";
        }
        cout <<endl;    
    }

    memset(buf,0,sizeof(buf));
    execute_pipe(test);

    //cout << "right before buf print" << endl;
    printf("buf:: \n");
    write(STDOUT_FILENO,buf,output_size);
}

int main(int argc, char** argv)
{
    test_execute_pipe();
}

1 个答案:

答案 0 :(得分:1)

您似乎假设您可以将任意数量的数据写入管道的一端,然后从另一端检索所有数据。但你不能。有一些缓冲可用但不多;如果你在阅读之前写的不止这些,write将会阻止。

另外,这个:

dup2(recursion_fd[0],STDIN_FILENO);

似乎认为recursion_fd已被设置为某种东西,但我不知道在哪里。