重定向
什么是重定向?一般情况下、Linux运行命令时都会打开三个文件:stdin(标准输入)、stdout(标准输出)、stderr(标准错误)。文件描述符分别为0、1、2。重定向就是把原本应该到标准输入、标准错误、标准输出的内容到file中。
重定向的本质是什么?例如,printf是c库中的IO函数,会把内容输出到stdout,在stdout底层访问文件的时候,找的还是fd为1的内容,但是当把fd的内容改为file的地址时,输出的消息就会往file之中。
看代码:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<fcntl.h>
6 #include<sys/types.h>
7 #include<sys/stat.h>
8
9 void do_exec(int argc,char*argv[])
10 {
11 pid_t pid = fork();
12 if(pid==0)
13 {
14 execvp(argv[0],argv);//进程替换
15 printf("command %d not found\n",argv[0]);
16 exit(1);
17 }
18 int s;
19 waitpid(pid,&s,0);
20 }
21
22 void do_parse(char *buf)//对输入的字符串进行解析,得到文件名,及命令行参数。
23 {
24 char *argv[8];
25 int argc = 0;
26 int flag = 0;
27 int i = 0;
28 for (i=0; buf[i];i++)
29 {
30 if(flag==0&&buf[i]!=' ')
31 {
32 argv[argc++]=buf+i;
33 flag=1;
34 }else if(buf[i]==' ')
35 {
36 flag=0;
37 buf[i] = '\0';
38 }
39 }
40 argv[argc] = NULL;
41 do_exec(argc,argv);
42 }
43
44 int main()
45 {
46 char buf[100];
47 while(1){
48
49 close(0);
50 int fd = open("./test",O_RDONLY);
51 if(fd == -1){perror("open");exit(1);}
52 printf("myshell>");
53 fflush(stdout);
54 memset(buf,0x00,sizeof(buf));
55 scanf("%[^\n]%*c",buf);
56 if(strncmp(buf,"exit",4)==0)
57 {
58 exit(0);
59 }
60
61 do_parse(buf);
62 }
63 }
shell实现原理:
Linux下一切皆文件,执行命令时,找到该命令所对应的文件,根据命令所对应的参数实现对应的操作。
shell实现:
获得执行命令:例如”ls -l”。do_parse()对命令进行解析得到”ls”,”-l”。”ls”为命令文件名,”-l”是命令行参数。fork()创建子进程,execvp()进程替换,
达到执行ls -l命令的操作。
实现如下:
首先,创建一个test文件,用来作为代替标准输入或标准输出。
编辑文件内容如下:
执行myshell,结果如下: