今天分享关于Linux下自主实现minishell重定向功能:
1.首先重定向是什么意思呢?
Linux重定向是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作,操作句柄为文件描述符,可以将文件描述符想象成两个指针,相当于指针所指的内容变了。
2.Linux下常用的shell重定向
当执行shell命令时,会默认打开3个文件,系统为这三个文件分配了文件标识符fd:
类型 | 文件描述符 | 默认情况 |
---|---|---|
标准输入(stdin) | 0 | 从键盘获得输入 |
标准输出(stdout) | 1 | 输出到屏幕 |
标准错误(stderr) | 2 | 输出到屏幕 |
常用到的两个输出重定向的符号">" 和 “>>”
第一个是清空重定向,会先清空文件的原有内容再向其中添加内容。
第二个属于追加重定向,直接在文件原有内容的末尾追加内容。
如果文件不存在都会先创建一个文件 !
看到这里我想你应该对重定向有个初步的认识了,那么现在就来实现下minishell的重定向,首先打开xshell6。
分析下重定向时需要你用拆解字符串的方式解析下用户输入的字符串,判断字符串的内容中是否有>或者>>这两个符号。
这里我就只给出关于重定的代码实现部分,其他的请看我的另一篇文章:
https://blog.youkuaiyun.com/Python_programer/article/details/89056198
函数部分代码实现如下:
51 char* redirect_file = NULL;
52 int do_redirect() //重定向符判断
53 {
54 redirect_flag = 0; //定义这个标记来区别>和>>
55 redirect_file = NULL; //
56 char* ptr = buf;
57 while(*ptr!='\0'){
58 if(*ptr=='>'){
59 redirect_flag = 1;
60 *ptr='\0';
61 ptr++;
62 if(*ptr=='>'){
63 redirect_flag = 2;
64 *ptr='\0';
65 ptr++;
66 }
67 while(*ptr!='\0'&&isspace(*ptr)){ //走完空格
68 ptr++;
69 }
70 redirect_file = ptr; //用redirect_file指针记录要重定向到的位置是在哪
71 while(*ptr!='\0'&&!isspace(*ptr)){ //走完非空的字符
72 ptr++;
73 }
74 *ptr='\0'; //走完一个非空字符串后加上\0
75 }
76 ptr++; //继续向下走
77 }
78 return 0;
79 }
主函数内相关部分:
102 int pid = fork(); //这个任务当然是交给子进程完成啦
103 if(pid<0){ //创建子进程失败,则继续创建,因为用户还要继续输入指令
104 printf("fork error!");
105 continue;
106 }
107 else if(pid==0){
108 int fd = 1;
109 if(redirect_flag == 1){ //如果是一个 <,则进行清空重定向
110 fd = open(redirect_file,O_WRONLY|O_CREAT|O_TR UNC,0664); //以只读方式,文件不存在则创建以及清空方式打开,后面的权限可以自己来定
111 if(fd<0){
112 exit(-1); //打开失败直接退出
113 }
114 }
115 else if(redirect_flag == 2){ //如果是一个 <<,则进行追加重定向
116 fd = open(redirect_file,O_WRONLY|O_CREAT|O_AP PEND,0664);
117 if(fd<0){
118 exit(-1);
119 }
120 }
121 dup2(fd,1); //将标准输出重定向到fd所指位置
完整的解析如上,重定向关键就是需要先判断是>还是>> ,然后记录下重定向符号后要重定向的位置,还有就是拆分用户输入命令为一个个字符串来解析!
下面来运行下我们所实现的代码:
将ls的结果清空的方式重定向到b.txt中,然后打开b.txt中可以看到结果,从而简单的实现了一个重定向的功能。