dup2重定向后的恢复

这周是留校的第二周,写shell分析参数着实难受,更难受的还在后面,由于自己shell的结构比较奇特,在fork之前已经进行了重定向,导致在excv执行程序之后结果无法打印到屏幕上。好生苦恼,好在万能的Google解决了这个问题,因此为大家分享一下。
咱们先来看个代码吧

#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
    int pid,sfd;
    int statues;
    char* argv1[10]={"ls",NULL};
    char* argv2[10]={"wc",NULL};
    int fd = open("file",O_RDWR|O_CREAT|O_TRUNC,0644);
    //sfd=dup(1);
    dup2(fd,1);
    if((pid=fork())==0)
    {
         execvp(argv1[0],argv1);
    }
    if(waitpid(pid,&statues,0)==-1)
    {
        printf("wait for child process error\n");
    }
    fd=open("file",O_RDONLY);
    dup2(fd,0);
    //dup2(sfd,1);
    dup2(1,fd); //错误做法
    execvp(argv2[0],argv2);
}

这个例子就是在shell环境下输入

ls > file | wc 

按照上面的代码,1已经变为了fd的拷贝,然后再将fd重定向到1相当于重定向fd自己。因此并不能起到恢复重定向的效果,因此wc所得结果会被重定向到文件file中,因此shell并不显示结果。
那么我们该怎么做才行?只需要将上面的注释去掉,然后再删除标错的代码就行了。
下来我们介绍一下dup系列。

#include <unistd.h>

       int dup(int oldfd);
       int dup2(int oldfd, int newfd);

利用函数dup,我们可以复制一个描述符。传给该函数一个既有的描述符,它就会返回一

个新的描述符,这个新的描述符是传给它的描述符的拷贝。这意味着,这两个描述符共享同一

个数据结构。
dup2函数跟dup函数相似,但dup2函数允许调用者规定一个有效描述符和目标描述符的id

。dup2函数成功返回时,目标描述符(dup2函数的第二个参数)将变成源描述符(dup2函数的

第一个参数)的复制品,换句话说,两个文件描述符现在都指向同一个文件,并且是函数第一

个参数指向的文件。
根据上面所诉,我们在使用dup2重定向标准输出后又需要恢复标准输出,只需在使用dup2重定向前,使用dup备份一下标准输出,待到需要恢复时将标准输出重定向回备份即可

猜你喜欢

转载自blog.csdn.net/Sanjiye/article/details/76403629