这周是留校的第二周,写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备份一下标准输出,待到需要恢复时将标准输出重定向回备份即可