【发布时间】:2023-04-04 16:57:01
【问题描述】:
所以我试图读取包含多个命令的行,并为每个命令创建一个子进程来处理它。一旦我尝试取消注释 stdout 重定向 的 if(fd2) 语句,我遇到了一些麻烦。所需的输出不是出现一次,而是出现多次。我不确定是什么原因造成的,我正在关闭所有文件描述符并让子退出。
我正在处理的命令可能同时具有标准输出和标准输入重定向,并且我成功地为标准输入设置了重定向,但我似乎找不到我的错误。我没有收到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 时,它应该合理地清除缓冲区,但我仍然得到相同的错误.
【问题讨论】:
-
你应该给minimal reproducible example。一旦我替换了(这里不完整的)
execvp并且当然删除了将转到重定向文件的printf("*STDOUT");,我就无法重现任何问题 -
@AlexHoppus 我继续按照问题中的建议添加了
fflush(0)。然而,这并没有解决我最初的问题。
标签: c fork file-descriptor dup2