所以我试图读取包含多个命令的行,并为每个命令创建一个子进程来处理它。一旦我尝试取消注释 stdout重定向的if(fd2)
语句,我就遇到了麻烦。它不是出现一次所需的输出,而是出现多次。我不确定是什么导致这种情况,我关闭所有文件描述符并让孩子退出。
我正在处理的命令可能同时具有stdout和stdin重定向,并且我成功设置了stdin的重定向,但我似乎无法找到我的bug。我没有收到perror()
警告。这不是dup2()
的问题,而是open()
的问题,如果我只是取消注释该部分,我会收到错误。
int concCmd(Cmd cmdM[], int iCmdCnt, Token tokenM[], int iTokenCnt){
long pid, wpid;
int i, status=0, fd = 0, fd2=0;
fflush(0);
for(i=0; i<iCmdCnt; i++){ //create a process for every command
pid=fork();
switch(pid){
case -1:
perror("Fork\n");
return 1;
case 0:
if(cmdM[i].iStdinRedirectIdx != 0){ //does command need stdin redirection
if((fd = open(tokenM[cmdM[i].iStdinRedirectIdx], O_RDONLY)) <0){
perror("open stdin");
return 1;
}
if((dup2(fd,STDIN_FILENO))<0){
perror("dup2");
return 1;
}
close(fd); //close in parent process
}
if(cmdM[i].iStdoutRedirectIdx != 0){ //command needs stdout redirection
// if((fd2 = open(tokenM[cmdM[i].iStdoutRedirectIdx], O_WRONLY|O_CREAT|O_EXCL)) < 0){
// perror("open stdout");
// return 1;
// }
// if((dup2(fd, STDOUT_FILENO))<0){
// perror("dup2");
// return 1;
// }
close(fd2);
}
//EXECVP HERE!!!
//execvp (cmdM[i].szCmdNm, tokenM[
exit(0);
default:
wpid = wait(&status);
close(fd);
close(fd2);
fprintf(stderr, "%ld %ld\n", (long)getpid(), wpid);
}
}
return 0;
}
我在开始分叉之前添加了一个fflush(0)
,以清除缓冲区,如另一个问题所示,这应该合理地清除缓冲区,当我为stdout调用open时,但我仍然得到了同样的错误。
答案 0 :(得分:0)
我打算发表评论,因为我想说的很简单,但我需要引用一些代码,所以也许发布答案更容易。
{
"Status":"OK",
"Series":[
{"ColorCode":"GREEN","ColorVal":40.5},
{"ColorCode":"RED","ColorVal":12.8},
{"ColorCode":"YELLOW","ColorVal":12.8}
]
}
在您的代码中,您在问题中发表评论的关于 // if((fd2 = open(tokenM[cmdM[i].iStdoutRedirectIdx], O_WRONLY|O_CREAT|O_EXCL)) < 0){
// perror("open stdout");
// return 1;
// }
// if((dup2(fd, STDOUT_FILENO))<0){
// perror("dup2");
// return 1;
// }
的部分有拼写错误。
fd2
应为dup2(fd, STDOUT_FILENO)
我不知道您的源代码中是否真的是一个拼写错误,或者您在发布问题时犯了错误。