Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Unix命令与C结合使用_C_Unix_Exec_Pipe - Fatal编程技术网

将Unix命令与C结合使用

将Unix命令与C结合使用,c,unix,exec,pipe,C,Unix,Exec,Pipe,我要模拟此Unix命令: cat file.txt | sort | tail -4 我遵循了这项技术,但它不起作用,它仍然被阻塞。 当有文件时,我可能需要使用其他东西。 我使用了两个管道,两个进程,在一个进程中使用了两个DUP,也许这是错误的 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> int main() { int p

我要模拟此Unix命令:

cat file.txt | sort | tail -4
我遵循了这项技术,但它不起作用,它仍然被阻塞。 当有文件时,我可能需要使用其他东西。 我使用了两个管道,两个进程,在一个进程中使用了两个DUP,也许这是错误的

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

int main()
{
  int p1[2];
  int p2[2];

  if(pipe(p1))
  {
    perror("pipe1");
    exit(0);
  }

  if(pipe(p2))
  {
    perror("pipe2");
    exit(0);
  }

  switch(fork())
  {
    case -1: perror(" fork1 error ");
             exit(0);

    case  0: close(STDOUT_FILENO);
             (void)dup(p1[1]);
             close(p1[1]);
             close(p1[0]);
             execlp("cat", "cat", "file.txt", NULL);
             exit(0);
    default: 
            switch(fork())
            {
              case -1: perror(" fork2 error ");
               exit(0);

              case  0: close(STDIN_FILENO);
                       (void)dup(p1[0]);
                       close(p1[1]);
                       close(p1[0]);

                       close(STDOUT_FILENO);
                       (void)dup(p2[1]);
                       close(p2[1]);
                       close(p2[0]);

                       execlp("sort", "sort", NULL);
                       exit(0);

              default: 
                       wait(NULL);
                       close(STDIN_FILENO);
                       (void)dup(p2[0]);
                       close(p2[0]);
                       close(p2[1]);
                       execlp("tail", "tail", "-4", NULL); 
            }             
  }
}

父进程从不关闭管道
p1
,因此其子进程会继续尝试读取管道。添加<代码>关闭(p1[0]);关闭(p1[1])
execlp之前(“tail”,“tail”,“-4”,NULL)


另外请注意,您不应该
等待(NULL)
:这是另一个等待发生的挂起,当file.txt很大并开始填充管道缓冲区时。

除非您这样做是为了学习,否则我建议使用libpipline——为什么调用wait(3)?直到两个进程结束我找到解决方案。问题是我没有按我应该的方式关闭管道。您可能需要dup2()而不是dup()。
g
f
d
b
c
a
e