您好我有以下问题,我必须创建一个程序来执行这些Linux命令ls –la | sort | wc –l
但是在我的代码中我只能读取这个命令中的两个,可以同一个人帮我这个吗?
int main(){
pid_t pids[3];
int dados[2],dados2[2],i;
if(pipe(dados) == -1 && pipe(dados2) == -1){
perror("pipe failed");
exit(1);
}
for(i=0;i<3;i++){
pids[i] = fork();
if(pids[i] == 0){
if(i==0){
close(dados[0]);
dup2(dados[1],1);
close(dados[1]);
execlp("ls","ls","-la",NULL);
perror("exec failed");
exit(-1);
}
if(i==1){
close(dados[1]);
dup2(dados[0],0);
close(dados[0]);
close(dados2[0]);
dup2(dados2[1],1);
close(dados2[1]);
execlp("sort","sort",NULL);
perror("exec failed");
exit(-1);
}else{
close(dados2[1]);
dup2(dados2[0],0);
close(dados2[0]);
printf("aaaaaaaaaaaaaaaaaa");
execlp("wc","wc","-l",NULL);
perror("exec failed");
exit(-1);
}
}
}
/* Pai tem de fechar a sua copia da extremidade de escrita
para a leitura do sort desbloquear */
close(dados[1]);
close(dados2[0]);
for(i=0;i<3;i++){
wait(NULL);
}
return 0;
}
我不明白这个错过了什么
答案 0 :(得分:0)
立刻引起我注意的是
-if(pipe(dados) == -1 && pipe(dados2) == -1){
+if(pipe(dados) == -1 || pipe(dados2) == -1){
perror("pipe failed");
exit(1);
}
父pid只需要读取最后一个命令的输出,因此父级需要关闭所有其他管道端。子进程需要关闭stdin / stdout和dup2()管道描述符以将它们绑定到stdin / stdout然后再绑定到exec()。使用管道,在流程中关闭不需要的管道末端非常重要。见http://linux.die.net/man/2/pipe
目前我没有一个linux盒子让我知道,所以我不能编写和测试linux代码。
我的总结是: - 父读取最后一个管道(链中最后一个进程的stdout) - 所有其他的孩子需要关闭()他们的stdin / stdout,dup2()右侧的pipeend,关闭所有不需要的管道(记得关闭dup2()源,因为它是一个fd)然后执行。
以下是我创建管道并重新绑定fds的示例。
// unset FD_CLOEXEC
set_close_on_exec(to_child,false);
set_close_on_exec(from_child, false);
// close and rebind the stdin/stdout/stderr
// dup the fd and recreate stdin/stdout with fd as the target
if (dup2(to_child, STDIN_FILENO) != 0 || dup2(from_child, STDOUT_FILENO) != 1) {
shared::perror("error duplicating socket for stdin/stdout");
exit(EXIT_FAILURE);
}
// close these FDs
close(to_child);
close(from_child);
// now we can exec the new sub process and talk to it through
// stdin/stdout/stderr
execlp(exe.c_str(), exe.c_str(), argv.c_str(), (char*)0);
// this should never be reached
shared::perror("error: executing the binary: " + exe);
exit(EXIT_FAILURE);
请记住,在pipe(int fds [2])处,索引1是管道的写入端,索引0是管道的读取端。所以你需要
此致 乔治
编辑:我推荐你的书“Linux编程接口:Linux和UNIX系统编程手册”ISBN-13:978-1593272203