我正在尝试在Unix中实现管道,并且已被要求以递归方式执行。我有一个sh程序,通过管道字符解析输入,然后分叉子进程开始管道。我将使用命令cat file | grep the | more
作为示例。
我的sh.c程序首先将输入字符串解析为pipeCmds,这只是一个指向输入字符串不同部分的char *数组。它分叉第一个子进程然后开始recursivePipe()调用,该调用应设置所有管道。管道设置完成后,我在这种情况下执行(“更多”)。
pid = fork();
if(pid == 0){
recursivePipe(pipeCmds[numCmds-2], numCmds-1);
exec(pipeCmds[numCmds-1]); // exec("more")
}else{
pid = wait(getpid());
}
这是recursivePipe函数,它应根据字符串中的命令数设置每个管道(即.numCmds)
int recursivePipe(char * cmd, int index){
/* cmd = more */
int pid, fd, copy;
int ttyfd;
char tty[64];
if(index < 1){
printf("index is 0... RETURN\n");
return;
}
pipe(pd);
// First fork a new child to stage the WRITING proc
printf("forking to %s from %s\n", cmd, pipeCmds[index]);
pid = fork();
if(pid == 0){
// Child
close(pd[0]); // Close the child's read
//if(index != (numCmds-2)){ // If we are not on the last command, make stdout be the pipe
dup2(pd[1], 1); // Place the WRITE end of the pipe into stdout so anything coming from the pipe
close(pd[1]);
//}
copy = dup(1);
close(1);
gettty(tty);
ttyfd = open(tty, O_WRONLY);
if(ttyfd == 1){
printf("exec(%s) from %s\n", cmd, pipeCmds[index]);
close(1);
dup(copy);
close(copy);
}
/*copy = dup(0);
close(0);
gettty(tty);
ttyfd = open(tty, O_RDONLY);
if(ttyfd == 0){
getc();
close(0);
dup(copy);
close(copy);
}*/
exec(cmd);
}else{
// Parent
printf("in parent: %s[%d]\n", pipeCmds[index], index);
close(pd[1]); // Close the parent's write since more doesn't have to write
//if(index != 0){ // If we are not on the first command, make stdin be the pipe
dup2(pd[0], 0); // Place the READ end of pipe into stdin so that more's stdin comes from the pipe
close(pd[0]);
//}
printf("lets recurse!: %s[%d]\n", pipeCmds[index], index);
// if(index > 0){
recursivePipe(pipeCmds[index-2], index-1); // This will set up all other procs too with correct pipes
//pid = wait(getpid());
// }
printf("done recurse!: %s[%d]\n", pipeCmds[index], index);
}
}
基本上,我尝试使用pipe(),然后在子进程中关闭管道的READ端并将stdout设置为现在的管道。所以在这种情况下,在第一次调用recursivePipe()时,父节是“more”proc,子节是“grep the”部分。所以“more”关闭它的stdin并用管道替换它,所以它读取“grep the”的所有输出
基于函数内部的printf(),这是该命令的输出:
forking to grep the from more
in parent: more[2]
lets recurse!: more[2]
forking to cat file from grep the
exec( grep the ) from more
exec(cat file) from grep the
in parent: grep the [1]
lets recurse!: grep the[1]
index is 0... RETURN
done recurse!: grep the [1]
done recurse!: more[2]
然后它似乎正确cat文件并将其发送到更多,但grep程序从未在两者之间使用。好像猫和更多人直接沟通而不是通过grep。
任何了解unix系统的人都可以帮我弄清楚为什么我的递归没有正确设置管道?感谢