Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.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
C 用两个子进程在我自己的shell中实现管道_C_Linux_Shell_Fork_Pipe - Fatal编程技术网

C 用两个子进程在我自己的shell中实现管道

C 用两个子进程在我自己的shell中实现管道,c,linux,shell,fork,pipe,C,Linux,Shell,Fork,Pipe,我在写我自己的外壳。下面是它的一部分。我想用两个子进程实现管道。 但当我执行下面的代码时,有些命令可以工作,有些则不行谁|排序“,”ls |排序“可以工作,但会|排序“,”cat file |排序“会让我的shell停止工作。我必须“cntrl+c”才能逃离我的外壳。我不明白为什么有些命令有效,有些命令无效。请有人指出我遗漏了什么 int pipefd[2]; int pipePos = checkPipePos(argc, argv); //find '|' command position

我在写我自己的外壳。下面是它的一部分。我想用两个子进程实现管道。 但当我执行下面的代码时,有些命令可以工作,有些则不行谁|排序“,”ls |排序“可以工作,但会|排序“,”cat file |排序“会让我的shell停止工作。我必须“cntrl+c”才能逃离我的外壳。我不明白为什么有些命令有效,有些命令无效。请有人指出我遗漏了什么

int pipefd[2];
int pipePos = checkPipePos(argc, argv); //find '|' command position in argv

if (pipe(pipefd) == -1) {
        printf("Creating pipe failed\n");
        return;
    }

    if (fork() == 0) {
        close(pipefd[0]);
        dup2(pipefd[1], 1);
        execlp(argv[0], argv[0], NULL);
    }

    if (fork() == 0) {
        close(pipefd[1]);
        dup2(pipefd[0], 0);
        execlp(argv[pipePos + 1], argv[pipePos + 1], NULL);
    }

    close(pipefd[0]);
    close(pipefd[1]);

    while (wait(NULL) >= 0);

我在这里看到一个可能的问题,它可能解释也可能解释不确定性的结果

在子进程中,复制管道的一个文件描述符后,不会关闭原始文件描述符

dup2(oldfd,newfd)
oldfd
复制到
newfd
上,但
oldfd
仍处于打开状态。
oldfd
newfd
文件描述符现在都指向同一个文件。请参阅dup2手册页

通常,在复制文件描述符后,您需要关闭()oldfd

因此,这里要发生的是,其中一个子进程将在
stdout
和其他一些随机文件描述符上具有相同的文件描述符,而另一个子进程将在
stdin
上具有相同的情况


这可能会也可能不会导致问题,具体取决于子进程的功能。无法确定,但您肯定要解决这个问题,看看它是否有帮助。

您的管道逻辑是正确的

ll | sort
不起作用,因为
ll
不是可执行文件

cat file | sort
不起作用,因为您没有传递
file
参数


Sam Varshavchik的改进是有效的。这是一个很好的解决办法,但不会引起任何严重的问题。它只会浪费一个文件描述符插槽。

是否将
ll
别名为
ls-al
?是的,对。在这种情况下它会影响吗??”ls | sort也可以,我想您可能使用了
execlp
错误。第一个参数不应该是路径吗?我认为如果我把arg放在第一个参数的位置,bash会自动找到路径。我错了吗?如果是,我如何修复它?Bash无法在您的程序中执行任何操作。一旦它开始执行您的程序,您就不再使用bash,而是在使用shell。最好在
execlp()
之后打印一条错误消息,以防失败。