所以我有一个任务,我必须处理管道中的n个命令.这些命令基于Linux.如果我的理解是正确的,我知道我必须创建一个for循环,不断地fork()主进程的子进程,并执行这些子进程,然后通过管道连接.这是我目前为止的代码.

void  main(void)
{
    char **cmds[3];
    char *c1[] = { "ls", "-l", "/etc", 0 };
    char *c2[] = { "head", "-n", "10", 0 };
    char *c3[] = { "tail", "-n", "5", 0 };
    cmds[0] = (char **)c1;
    cmds[1] = (char **)c2;
    cmds[2] = (char **)c3; 
    
    int pid, status;
    pid = fork();
    
    if(pid == 0){//child proccess
        int fd[2];
        int infd;
        int i;
        for(i = 0; i < 2; i++){
            pipe(fd);
            int ppid;
            ppid = fork();
            
            if(ppid > 0){
                dup2(fd[1], 1);
                close(fd[0]);
                //executes the nth command
                execvp(*(cmds+i)[0], *(cmds+i));
            }else if(ppid == 0){
                dup2(fd[0], 0);
                close(fd[1]);
                //executes the n+1th command
                execvp(*(cmds+i+1)[0], *(cmds+i+1));
            }
        }
    }else if (pid > 0){//parents proccess
        while((pid = wait(&status)) != -1);
        
    }
}

就目前的程序而言,我只能传输第一个和第二个命令,但由于某些原因,第三个命令完全没有被检测到.我该怎么解决这件事?

推荐答案

以下是您要创建的三个进程:

stdin  ->  ls    ->  pipe1
pipe1  ->  head  ->  pipe2
pipe2  ->  tail  ->  stdout

您一次最多创建一个管道,但head个管道需要与两个管道通信.

循环的基础是进程的创建,而不是管道的创建.这意味着您将需要将管道信息从一个通道传送到另一个通道.

pid_t pids[ num_cmds ];

int next_stdin_fd = 0;

for (int i = 0; i < num_cmds; ++i ) {
   int stdin_fd = next_stdin_fd;
   int stdout_fd;

   if ( i == num_programs - 1 ) {
      next_stdin_fd = -1;
      stdout_fd     = 1;
   } else {
      int pipe_fds[2];
      pipe( pipe_fds );
      next_stdin_fd = pipe_fds[ 0 ];
      stdout_fd     = pipe_fds[ 1 ];
   }

   pids[ i ] = fork();
   if ( pid == 0 ) {
      if ( stdin_fd != 0 ) {
         dup2( stdin_fd, 0 );
         close( stdin_fd );
      }

      if ( stdout_fd != 1 ) {
         dup2( stdout_fd, 1 );
         close( stdout_fd );
      }

      if ( next_stdin_fd != -1 ) {
         close( next_stdin_fd );
      }

      execvp( *cmds[i], cmds[i]+1 );
   }

   if ( stdout_fd != 1 ) {
      close( stdout_fd );
   }
}

for (int i = 0; i < num_cmds; ++i ) {
   int status;
   waitpid( pids[ i ], &status, 0 );
}

为简洁起见,省略了错误判断.

C++相关问答推荐

%p与char* 等组合缺少的GCC Wform警告

使用单个字节内的位字段

返回一个包含数组的 struct

使用NameSurname扫描到两个单独的字符串

两个连续的语句是否按顺序排列?

如何使fputs功能提示错误输入并要求用户重新输入.程序停止而不是请求新的输入

为什么I2C会发送错误的数据?

识别和处理c中整数溢出的最佳方法?

GTK3按钮信号错误

如何在GDB中查看MUSL的源代码

关于scanf()和空格的问题

为什么这个分配做得不好呢?

安全倒计时循环

将 struct 数组写入二进制文件时发生Valgrind错误

是否有单独的缓冲区用于读写库调用?

try 判断长整数是否为素数

我的代码可以与一个编译器一起使用,但不能与其他编译器一起使用

使用共享变量同步多线程 C 中的函数

在 C/C++ 中原子按位与字节的最佳方法?

设置具有非零终止字符串的大整数