我使用pipe,fork,dup2来实现“ls |更多“或”ls |排序等 我在这里无法理解这个问题。 当我运行我的程序时,我收到此错误:
./a.out
Missing filename ("less --help" for help)
我为什么得到"少" ??
这段代码有什么问题?如果我再次将“更多”更改为“ls”,则可以正常工作。我的意思是,它就像做ls | LS。
#define STDIN 0
#define STDOUT 1
int main()
{
int fd[2];
int pid;
char *lschar[20]={"ls",NULL};
char *morechar[20]={"more",NULL};
pid = fork();
if (pid == 0) {
/* child */
int cpid;
cpid = fork();
if(cpid == 0) {
//printf("\n in ls \n");
pipe(fd);
dup2(fd[1], STDOUT);
close(fd[0]);
close (fd[1]);
execvp("ls",lschar);
} else if(cpid>0) {
waitpid(cpid, NULL,0);
dup2(fd[0],STDIN);
close(fd[0]);
close(fd[1]);
execvp("more", morechar);
}
} else if (pid > 0) {
/* Parent */
waitpid(pid, NULL,0);
}
return 0;
}
感谢您的帮助。
答案 0 :(得分:6)
您的主要问题在于您pipe()
来电的放置。您必须在 fork()
之前将其称为:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#define STDIN 0
#define STDOUT 1
int main()
{
int fd[2];
int pid;
char *lschar[20]={"ls",NULL};
char *morechar[20]={"more", NULL};
pid = fork();
if (pid == 0) {
/* child */
int cpid;
pipe(fd);
cpid = fork();
if(cpid == 0) {
//printf("\n in ls \n");
dup2(fd[1], STDOUT);
close(fd[0]);
close (fd[1]);
execvp("ls",lschar);
} else if(cpid>0) {
dup2(fd[0],STDIN);
close(fd[0]);
close(fd[1]);
execvp("more", morechar);
}
} else if (pid > 0) {
/* Parent */
waitpid(pid, NULL,0);
}
return 0;
}
否则,更多进程没有正确的文件描述符。此外,更多进程中的waitpid()是有问题的和不必要的(更多将等待自己的输入)。如果ls的输出特别长,则管道可能会变满,导致ls阻塞其写入。结果是死锁,它永远等待。因此,我还删除了有问题的waitpid()
电话。
另外,如果你仔细检查pipe()
和dup2()
这样的函数的返回值,那么这个错误会更容易找到 - 你会看到你的{{1失败了。