我目前正在写我自己的壳实施C.我的理解后面的管道和重定向FDS原则。然而,一些具体的管道行为引起了我的注意:管在自己的壳实现链接
- cat | ls(或任何不从stdin读取的命令作为管道的最终元素)。
在这种情况下,shell中会发生什么情况是ls执行并且猫在退出之前请求单行(由我猜测得到的SIGPIPE导致)。我曾试图按照本教程以更好地了解多个管道背后的原则:http://web.cse.ohio-state.edu/~mamrak.1/CIS762/pipes_lab_notes.html
下面是一些代码,我已经写了,试图复制我要找的行为:
char *cmd1[] = {"/bin/cat", NULL};
char *cmd2[] = {"/bin/ls", NULL};
int pdes[2];
pid_t child;
if (!(child = fork()))
{
pipe(pdes);
if (!fork())
{
close(pdes[0]);
dup2(pdes[1], STDOUT_FILENO);
/* cat command gets executed here */
execvp(cmd1[0], cmd1);
}
else
{
close(pdes[1]);
dup2(pdes[0], STDIN_FILENO);
/* ls command gets executed here */
execvp(cmd2[0], cmd2);
}
}
wait(NULL);
我所知道的该实现的安全缺陷,但这仅仅用于测试。这个代码的问题是,我知道每当ls被执行时,它就会退出,然后cat以某种方式在后台运行(并且在我的情况下失败,因为它会在我的程序退出时尝试在zsh提示符下读取)。我无法找到解决方案,使它像应该那样工作。因为如果我一个一个地等待命令,那么这样的命令如cat/dev/random |如果任何人有这个问题的解决方案,或者至少提供一些指导,将不胜感激头〜10会永远运行下去......
。
我不感兴趣的命令任何用处。我只是在复制bash的行为,这是有兴趣的:首先显示LS的输出,并运行猫将只需要一条线,然后(即提示一行的用户) –
在你的榜样,'cat'成为同时'孙子ls'是一个孩子。 'wait'只等待'ls'。你应该让'猫'和'ls'直接的孩子,然后等待两者。 –
@thatotherguy确实,我刚刚尝试过您的解决方案,它绝对有效。而且这个解决方案似乎接近了我链接的教程中提供的第一个想法。但是,如果我想要扩展多个命令,会发生什么?这就是为什么第二个实现看起来更有趣的原因!我应该可以有很多链接命令。有了这个解决方案,看起来我必须事先知道我有多少个命令来准备管道和叉子没有? –