C++11 使用fork和exec进行管道化后不显示输出

C++11 使用fork和exec进行管道化后不显示输出,c++11,pipe,fork,exec,C++11,Pipe,Fork,Exec,我正在尝试创建一个函数,该函数运行一个命令,然后通过管道将输出传输到第二个命令并运行该命令。我在无限循环中运行函数。问题是,该函数第一次工作,但之后不会显示任何内容。 例如,当我运行ls | wc-l时,它第一次显示正确的结果,但当我在之后运行它时,我没有得到任何输出 这是我的函数(解析在另一个函数中处理): void系统_管道(std::string command1,std::string command2) { 智力状态; int-fd[2]; int-fd2[2]; 管道(fd); in

我正在尝试创建一个函数,该函数运行一个命令,然后通过管道将输出传输到第二个命令并运行该命令。我在无限循环中运行函数。问题是,该函数第一次工作,但之后不会显示任何内容。 例如,当我运行
ls | wc-l
时,它第一次显示正确的结果,但当我在之后运行它时,我没有得到任何输出

这是我的函数(解析在另一个函数中处理):

void系统_管道(std::string command1,std::string command2)
{
智力状态;
int-fd[2];
int-fd2[2];
管道(fd);
int-pid=fork();
//子进程。
如果(pid==0)
{
std::shared_ptr temp=string_to_char(command1);
char*name[]={”/bin/bash“,“-c”,temp.get(),NULL};
关闭(fd[0]);
dup2(fd[1],1);
execvp(名称[0],名称);
退出(退出失败);
}
//父进程。
其他的
{
std::shared_ptr temp=string_to_char(command2);
char*name[]={”/bin/bash“,“-c”,temp.get(),NULL};
关闭(fd[1]);
dup2(fd[0],0);
waitpid(pid和status,0);
//my_系统(命令2);
//Fork并在这里执行一个新进程。
int-pid2=fork();
如果(pid2==0)
{
execvp(名称[0],名称);
退出(退出失败);
}
其他的
{
waitpid(pid2,NULL,0);
}
}
如果(状态)
标准::cout
第二个问题是管道文件处于打开状态。
这不是一个好的编码示例,但它只是为了说明它应该如何工作

// ( g++ -std=c++11  )
// type `ls | grep file.cxx`
#include <iostream>
#include <string>
#include <cstring>
#include <array> 
#include <memory>

#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void replace_with ( std::string command )
{
    char exec_name [] = "bash" , arg [] = "-c" ;
    char * line [] = { exec_name , arg , &command[ 0 ] , nullptr } ;
    execvp( exec_name , line ) ;
}

void pipeline ( const std::string& command0 , const std::string& command1 )
{
    std::array< int , 2 > pipe_fd ; enum { READ_END , WRITE_END } ; 

    if ( pipe( pipe_fd.data() ) ) throw std::runtime_error( "can't create a pipe" ) ;

    int id = fork() ;
    if ( id < 0 ) { for ( auto each : pipe_fd ) close( each ) ;
                    throw std::runtime_error( "can't create a child" ) ; }

    if ( ! id ) /* child */
    {
        close( pipe_fd[ READ_END ] ) ; 
        dup2( pipe_fd[ WRITE_END ] , STDOUT_FILENO ) ;
        close( pipe_fd[ WRITE_END ] ) ; //

        replace_with( command0 ) ;
    }
    else /* parent */
    {
        close( pipe_fd[ WRITE_END ] ) ;
        waitpid( id , nullptr , 0 ) ;
        int id_second = fork () ;
        if ( id_second > 0 ) waitpid( id_second , nullptr , 0 ) ;
        else if ( ! id_second ) /* child */ 
        {
            dup2( pipe_fd[ READ_END ] , STDIN_FILENO ) ;
            close( pipe_fd[ READ_END ] ) ; //
            replace_with( command1 ) ;
        }

        close( pipe_fd[ READ_END ] ) ;
    }
}

int main () try
{
    while ( true )
    {
        std::string command0 , command1 ;
        getline( std::cin , command0 , '|' ) ;
        getline( std::cin , command1 ) ;
        pipeline( command0 , command1 ) ;
    }

} catch ( const std::runtime_error& e ) 
  { std::cerr << e.what() ; return - 1 ; }
/(g++-std=c++11)
//键入`ls | grep file.cxx`
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
void replace_为(std::string命令)
{
char exec_name[]=“bash”,arg[]=“-c”;
char*line[]={exec_name,arg,&命令[0],nullptr};
execvp(exec_名称,行);
}
无效管道(常量标准::字符串和命令0,常量标准::字符串和命令1)
{
数组管道fd;枚举{READ\u END,WRITE\u END};
if(pipe(pipe_fd.data())抛出std::runtime_错误(“无法创建管道”);
int id=fork();
如果(id<0){for(auto-each:pipe_-fd)关闭(each);
抛出std::runtime_错误(“无法创建子项”);}
如果(!id)/*子级*/
{
关闭(管道fd[读取结束]);
dup2(管道fd[写入结束],标准输出文件号);
关闭(管道fd[写入结束])//
将_替换为(command0);
}
else/*家长*/
{
关闭(管道fd[写入结束]);
waitpid(id,nullptr,0);
int id_second=fork();
如果(id_second>0)waitpid(id_second,nullptr,0);
如果(!id_second)/*子项*/
{
dup2(管道fd[读取端],标准文件号);
关闭(管道fd[读取结束])//
将_替换为(command1);
}
关闭(管道fd[读取结束]);
}
}
int main()尝试
{
while(true)
{
std::字符串command0,command1;
getline(std::cin,command0,“|”);
getline(标准::cin,command1);
管道(command0、command1);
}
}捕获(const std::runtime_error&e)
{std::cerr
while(true)
{
    string line;
    getline(cin, line);
    pair<string, string> commands = parse(line);
    system_pipe(commands.first, commands.second);
}
else
 { 
        std::shared_ptr<char> temp = string_to_char(command2);
        char *name[] = {"/bin/bash", "-c", temp.get(), NULL};   

        close(fd[1]);
        dup2(fd[0], 0);
        waitpid(pid, &status, 0);
        //my_system(command2);
int pid2 = fork();
if (pid2 == 0)
{
    dup2(fd[0], 0); // here.
    execvp(name[0], name);
    exit(EXIT_FAILURE);
}
// ( g++ -std=c++11  )
// type `ls | grep file.cxx`
#include <iostream>
#include <string>
#include <cstring>
#include <array> 
#include <memory>

#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void replace_with ( std::string command )
{
    char exec_name [] = "bash" , arg [] = "-c" ;
    char * line [] = { exec_name , arg , &command[ 0 ] , nullptr } ;
    execvp( exec_name , line ) ;
}

void pipeline ( const std::string& command0 , const std::string& command1 )
{
    std::array< int , 2 > pipe_fd ; enum { READ_END , WRITE_END } ; 

    if ( pipe( pipe_fd.data() ) ) throw std::runtime_error( "can't create a pipe" ) ;

    int id = fork() ;
    if ( id < 0 ) { for ( auto each : pipe_fd ) close( each ) ;
                    throw std::runtime_error( "can't create a child" ) ; }

    if ( ! id ) /* child */
    {
        close( pipe_fd[ READ_END ] ) ; 
        dup2( pipe_fd[ WRITE_END ] , STDOUT_FILENO ) ;
        close( pipe_fd[ WRITE_END ] ) ; //

        replace_with( command0 ) ;
    }
    else /* parent */
    {
        close( pipe_fd[ WRITE_END ] ) ;
        waitpid( id , nullptr , 0 ) ;
        int id_second = fork () ;
        if ( id_second > 0 ) waitpid( id_second , nullptr , 0 ) ;
        else if ( ! id_second ) /* child */ 
        {
            dup2( pipe_fd[ READ_END ] , STDIN_FILENO ) ;
            close( pipe_fd[ READ_END ] ) ; //
            replace_with( command1 ) ;
        }

        close( pipe_fd[ READ_END ] ) ;
    }
}

int main () try
{
    while ( true )
    {
        std::string command0 , command1 ;
        getline( std::cin , command0 , '|' ) ;
        getline( std::cin , command1 ) ;
        pipeline( command0 , command1 ) ;
    }

} catch ( const std::runtime_error& e ) 
  { std::cerr << e.what() ; return - 1 ; }