两个 Children 执行 ls -la | grep 使用管道
Two Children to execute ls -la | grep using pipes
嘿,我在理解这段代码失败的地方时遇到了问题。
它可能在执行 execvpe(grep) 的地方失败(控制台:"Grep Error")。
代码如下:
int main(int argc, char *argv[]){
printf("filter.c\n");
int fd[2];
pid_t ls,grep;
if(argc<3){
printf("Bitte 2 Argumente angeben <Verzeichnis> <Suchmuster>");
exit(-1);
}
char verzeichnis[256];
char suchmuster [256];
char kind [256];
strcpy(verzeichnis,argv[1]);
strcpy(suchmuster ,argv[2]);
if(pipe(fd)<0){
printf("Pipe fehlgeschlagen\n");
return -1;
}
if((ls=fork())==-1){
//fehler
printf("Fork ls fehlgeschlagen\n");
exit(-1);
} else if(ls==0){
//kind
printf("\nChild1 laueft(ls)\n");
if(dup2(fd[1],STDOUT_FILENO)==-1){//dupliziert fd[1]
printf("Dup failed(ls)\n");
return -1;
}
close(fd[0]);
close(fd[1]);
char *argu[]={"-la",verzeichnis,NULL};
if(execvpe("bin/ls",argu,NULL)==-1){//EXECVE
printf("ls error");
return -1;
}
return -1 }
if((grep=fork())==-1){
//fehler
printf("Forken von grep fehlgeschlagen\n");
return -1;
} else if(grep==0){
//children2
printf("Child 2 lauft (grep)\n");
if(dup2(fd[0],STDIN_FILENO)==-1){
printf("dup2 fd[0] fehlgeschlagen\n");
return -1;
}
close(fd[0]);
close(fd[1]);
char *argu[]={"bin/grep",suchmuster,NULL};
if(execvpe("bin/grep",argu,NULL)==-1){
printf("Grep error");
return -1;
}
return -1;
}
close(fd[0]);
close(fd[1]);
while(wait(NULL)>0);//while()
return 0;
// exit(0);
}
所以我想在写入和/或读取 to/from 管道时出现问题。有人知道我的问题吗? :/
如果给定的可执行文件路径包含 /
字符,则不执行搜索。在这种情况下,如有必要,相对于调用时进程的当前工作目录解析给定路径。这很少是一个人想要的,你的情况看起来也不例外。此外,如果您确实要指定二进制文件的路径而不是简单的名称,那么您从 exec.
的路径搜索变体中得不到任何好处。
此外,execvpe()
的最后一个参数应该是指向 char *
的以 NULL 结尾的数组的第一个元素的指针。尽管指向的数组可能除了终止符之外没有其他元素,但我找不到任何文档表明允许参数本身为 NULL
。如果你确实想为执行程序指定空环境,那么,两个 execvpe()
调用都应该采用这种一般形式:
char *argu[] = { "grep", suchmuster, NULL };
char *env[] = { NULL };
if (execvpe("/bin/grep", argu, env) == -1) {
此外,在空环境下执行外部进程是值得怀疑的,尽管不一定是错误的。出于这个目的,我看不出有多大优势,您可以通过使用一个 exec 函数来为自己省去一些麻烦,该函数只向 exec 图像提供调用进程环境的副本。例如,execvp()
将是最接近 execvpe()
且具有该特征的那个。
此外,将程序参数打包到一个数组中似乎有点愚蠢,您只 用于 exec 调用。 exec 的 varargs 变体避免了这样做的任何需要(execl()
,等等)。
exec 函数 return 仅在出错时运行。您 可以 测试 return 值,但是如果这些函数 return 根本没有,那么它们的 return 值总是 -1。
因此,考虑到所有这些因素,假设可以提供 grep
和 ls
父进程环境的副本,这是我建议的一般形式执行调用:
execl("/bin/grep", "grep", suchmuster, NULL);
// an error occurred
perror("execing grep");
_Exit(1);
嘿,我在理解这段代码失败的地方时遇到了问题。 它可能在执行 execvpe(grep) 的地方失败(控制台:"Grep Error")。
代码如下:
int main(int argc, char *argv[]){
printf("filter.c\n");
int fd[2];
pid_t ls,grep;
if(argc<3){
printf("Bitte 2 Argumente angeben <Verzeichnis> <Suchmuster>");
exit(-1);
}
char verzeichnis[256];
char suchmuster [256];
char kind [256];
strcpy(verzeichnis,argv[1]);
strcpy(suchmuster ,argv[2]);
if(pipe(fd)<0){
printf("Pipe fehlgeschlagen\n");
return -1;
}
if((ls=fork())==-1){
//fehler
printf("Fork ls fehlgeschlagen\n");
exit(-1);
} else if(ls==0){
//kind
printf("\nChild1 laueft(ls)\n");
if(dup2(fd[1],STDOUT_FILENO)==-1){//dupliziert fd[1]
printf("Dup failed(ls)\n");
return -1;
}
close(fd[0]);
close(fd[1]);
char *argu[]={"-la",verzeichnis,NULL};
if(execvpe("bin/ls",argu,NULL)==-1){//EXECVE
printf("ls error");
return -1;
}
return -1 }
if((grep=fork())==-1){
//fehler
printf("Forken von grep fehlgeschlagen\n");
return -1;
} else if(grep==0){
//children2
printf("Child 2 lauft (grep)\n");
if(dup2(fd[0],STDIN_FILENO)==-1){
printf("dup2 fd[0] fehlgeschlagen\n");
return -1;
}
close(fd[0]);
close(fd[1]);
char *argu[]={"bin/grep",suchmuster,NULL};
if(execvpe("bin/grep",argu,NULL)==-1){
printf("Grep error");
return -1;
}
return -1;
}
close(fd[0]);
close(fd[1]);
while(wait(NULL)>0);//while()
return 0;
// exit(0);
}
所以我想在写入和/或读取 to/from 管道时出现问题。有人知道我的问题吗? :/
如果给定的可执行文件路径包含 /
字符,则不执行搜索。在这种情况下,如有必要,相对于调用时进程的当前工作目录解析给定路径。这很少是一个人想要的,你的情况看起来也不例外。此外,如果您确实要指定二进制文件的路径而不是简单的名称,那么您从 exec.
此外,execvpe()
的最后一个参数应该是指向 char *
的以 NULL 结尾的数组的第一个元素的指针。尽管指向的数组可能除了终止符之外没有其他元素,但我找不到任何文档表明允许参数本身为 NULL
。如果你确实想为执行程序指定空环境,那么,两个 execvpe()
调用都应该采用这种一般形式:
char *argu[] = { "grep", suchmuster, NULL };
char *env[] = { NULL };
if (execvpe("/bin/grep", argu, env) == -1) {
此外,在空环境下执行外部进程是值得怀疑的,尽管不一定是错误的。出于这个目的,我看不出有多大优势,您可以通过使用一个 exec 函数来为自己省去一些麻烦,该函数只向 exec 图像提供调用进程环境的副本。例如,execvp()
将是最接近 execvpe()
且具有该特征的那个。
此外,将程序参数打包到一个数组中似乎有点愚蠢,您只 用于 exec 调用。 exec 的 varargs 变体避免了这样做的任何需要(execl()
,等等)。
exec 函数 return 仅在出错时运行。您 可以 测试 return 值,但是如果这些函数 return 根本没有,那么它们的 return 值总是 -1。
因此,考虑到所有这些因素,假设可以提供 grep
和 ls
父进程环境的副本,这是我建议的一般形式执行调用:
execl("/bin/grep", "grep", suchmuster, NULL);
// an error occurred
perror("execing grep");
_Exit(1);