我正在编写一个运行Linux命令的C程序,如:
$ cat / etc / passwd | cut -f1 -d:|排序
这个想法是使用fork()创建子进程以使用execlp()运行命令。我计划使用两个管道进行通信,并使用dup()指示输入输出。
输出错误:
ls -l | wc -c on命令返回1746 该计划返回1761
代码(编辑以反映建议):
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
int main()
{
int i,fd1[2],status,listpid[2];
pid_t child;
pipe(fd1);
for(i=0; i< 2; i++)
{
printf("\ncreating child\n");
if((child = fork()) == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
else if(child == 0)
{
if(i == 0)
{
close(1); dup(fd1[1]);
close(fd1[0]);
close(fd1[1]);
printf("\nrunning ls -l\n");
fflush(stdout);
execlp("ls","ls","-l", (char *)NULL);
exit(EXIT_SUCCESS);
}
else if(i == 1)
{
close(0); dup(fd1[0]);
close(fd1[1]);
close(fd1[0]);
printf("\nrunning wc -c\n");
fflush(stdout);
execlp("wc","wc","-c", (char *)NULL);
exit(EXIT_SUCCESS);
}
}
else
{
listpid[i]=child;
}
}
close(fd1[0]);
close(fd1[1]);
for(i = 0; i < 2; i++)
{
waitpid(listpid[i], &status, 0);
if(WIFEXITED(status))
{
printf("\n[%d] TERMINATED (Status: %d)\n",listpid[i], WEXITSTATUS(status));
}
}
exit(EXIT_SUCCESS);
}
答案 0 :(得分:1)
首先你不能在循环中等待 - 如果ls的输出足够大,它会填满管道,所以直到有人读取它才会完成:你必须在for循环之后等待两个孩子。 第二 - 只要管道的另一端打开,wc就会继续,即你必须关闭父管道。
答案 1 :(得分:0)
更新后,两个子进程的行为正常。但是,您仍需要添加:
close(fd1[0]);
close(fd1[1]);
在启动子项的for
循环和收集退出状态的for
循环之间。
由于管道的写入端仍处于打开状态,wc
未收到EOF,因此它不会终止,因此您的进程无限期地等待。