C 用两个子进程在我自己的shell中实现管道
我在写我自己的外壳。下面是它的一部分。我想用两个子进程实现管道。 但当我执行下面的代码时,有些命令可以工作,有些则不行谁|排序“,”ls |排序“可以工作,但会|排序“,”cat file |排序“会让我的shell停止工作。我必须“cntrl+c”才能逃离我的外壳。我不明白为什么有些命令有效,有些命令无效。请有人指出我遗漏了什么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
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()
之后打印一条错误消息,以防失败。