我正在尝试使用管道将一个命令的标准输出链接到另一个命令的标准输入。例如模仿(cmd1 | cmd2)。
以下是我代码的大幅简化版本。
在这个程序中,我试图创建一个管道,将第一个执行文件的标准输出重定向到第二个执行文件的标准输入。当我尝试使用"ls | wc"作为我的执行文件时,程序在第二个执行文件处挂起。然而,当我使用一个简单的程序"./addone"作为我的执行文件时,整个执行过程成功完成。
其中,"addone"是一个小程序:
以下是我代码的大幅简化版本。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argC, char *argv[])
{
//Run first command
int fds[2];
if (pipe (fds) < 0) { //Create pipe
fprintf (stderr, "Pipe Failed\n");
}
int pid;
if ((pid = fork ()) == -1) {
fprintf (stderr, "Fork 1 Failed\n");
exit (1);
}
if (pid == 0) { //First child proccess
close (fds[0]); //Close input end of pipe
dup2 (fds[1], STDOUT_FILENO); //Set stdout to output pipe
close (fds[1]); //Close output end of pipe
fprintf (stderr, "Exec 1 executing now\n");
execlp ("./addone", "./addone", NULL); //execute first command - Doesnt cause hang
//execlp("ls", "ls", NULL);//Causes hang
fprintf (stderr, "Exec 1 failed\n");
} else { //First parent segment
int returnStatus;
waitpid (pid, &returnStatus, 0); //Wait for child 1 to finish
fprintf (stderr, "Back to parent 1\n");
}
//Run second command
if ((pid = fork ()) == -1) {
fprintf (stderr, "Fork 2 failed\n");
}
if (pid == 0) { //second child proccess
dup2 (fds[0], STDIN_FILENO); //Set stdin to input pipe
close (fds[0]); //Close input end of pipe
close (fds[1]); //Close output end of pipe
fprintf (stderr, "Exec 2 executing now\n");
execlp ("./addone", "./addone", NULL); //execute first command - Doesnt cause hang
//execlp("wc", "wc", NULL);//Causes hang
fprintf (stderr, "Exec 2 failed\n");
} else { //second parent segment
int returnStatus;
waitpid (pid, &returnStatus, 0); //Wait for child 2 to finish
fprintf (stderr, "Back to parent 2\n");
//Done with pipes
close (fds[0]);
close (fds[1]);
}
return 0;
}
在这个程序中,我试图创建一个管道,将第一个执行文件的标准输出重定向到第二个执行文件的标准输入。当我尝试使用"ls | wc"作为我的执行文件时,程序在第二个执行文件处挂起。然而,当我使用一个简单的程序"./addone"作为我的执行文件时,整个执行过程成功完成。
其中,"addone"是一个小程序:
#include<stdio.h>
int main(){
int value = 0;
scanf("%d", &value);
value++;
printf("%d\n", value);
}
有人建议我的问题可能是由于输入管道被保持打开状态,但我无法确定发生在哪里,而且这并不能解释为什么当使用我的简单测试程序时,我的程序可以完美运行。
如果您能提供任何关于导致这个问题的原因的建议,将不胜感激。
pipe
在fork
之前被调用,所以它在父进程和子进程中均打开。对于您的简单程序来说,这不是问题,因为它不像wc
那样循环等待EOF
。只要管道仍由任何进程保持打开状态,EOF
就永远不会出现。 - kaylumwaitpid
之前你必须这样做。否则子进程不会退出,而waitpid
永远不会解除阻塞。 - kaylum