Linux 写一个自己的bash1.0版本
1、什么是bash?
bash是 Bourne Again Shell 的缩写,是linux默认的标准shell(也是大家常说的系统内核),bash也是Unix/Linux上常见的Shell脚本解释器,既然bash是标准的shell,那么就有非标准的sh,csh,ksh等等,我们常说有多少种Shell,其实说的是Shell脚本解释器,Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本,bash是基于Bourne shell创建的,并且吸收了C shell和Korn shell的一些特性,而且bash完全兼容sh,也就是说,用sh写的脚本可以不加修改的在bash中执行。如下:
2、分析如何写一个自己的bash
因为我们需要编写一个程序来生成自己的bash,所以当我们执行自己的程序时,需要生成一个bash进程来替换当前进程,我们都知道产生一个新进程是分两步来完成的,第一步:调用fork()生成一个子进程,第二步:进程替换
3、写代码mybash.c:
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<unistd.h>
5 #include<sys/wait.h>
6
7 char* get_cmd (char buff[],char* myargv[])
8 {
9 if ( buff == NULL || myargv == NULL)
10 {
11 return NULL;
12 }
13
14 char* s = strtok(buff," ");
15 int i = 0;
16 while( s != NULL )
17 {
18 myargv[i++] = s;
19 s = strtok(NULL," ");
20 }
21 return myargv[0];
22 }
23 int main()
24 {
25 while(1)
26 {
27 char buff[128] = { 0 };
28 printf("wys@DESKTOP-2OU3HRV:~$");
29 fflush(stdout);//刷新缓冲区 使printf函数中的内容输出
30
31 fgets(buff,128,stdin);//键盘输入的命令和参数
32 buff[strlen(buff) - 1] = 0;//去掉最后的\n
33
34 char* myargv[10] = { 0 };
35 char* cmd = get_cmd(buff,myargv);
36 if(cmd == NULL)
37 {
38 continue; //如果命令为空,结束本次循环,重新输入
39 }
40 else if (strcmp(cmd,"exit") == 0)
41 {
42 break;//如果输入的是exit就直接退出程序
43 }
44 else
45 {
46 //fork() + exec
47 pid_t pid = fork();
48 if ( pid == -1 )
49 {
50 printf("fork error\n");
51 continue;
52 }
53 if (pid == 0) //fork()成功
54 {
55 //替换进程
56 execvp(cmd,myargv);
57 printf("exec error\n");//如果程序执行到本行,则替换失败
58 exit(0);
59 }
60 wait(NULL);//父进程调用wait(),避免产生僵尸进程,因为不用关心子进程的退出码,
61 //只是不想让子进程变成僵尸进程,所以参数为NULL
62 }
63 }
64 }
4.编译运行
通过分析运行结果我们发现,mybash的父进程是bash,ps -f 的父进程是mybash。
5、可以改变printf()函数中内容的颜色
在调试程序时,有时候要输出大量数据,如果让printf/fprintf改变输出数据的颜色,那观察数据就方便多了。终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关。转义序列是以 ESC 开头,可以用 /033 完成相同的工作(ESC 的 ASCII 码用十进制表示就是 27, = 用八进制表示的 33)。
1)格式如下:
\033[显示方式;前景色;背景色m
\033[0m 默认
\033[1;32;40m 绿色
\033[1;31;40m 红色
2)显示方式:
0(默认值)、1(高亮)、22(非粗体)、4(下划线)、24(非下划线)、5(闪烁)、25(非闪烁)、7(反显)、27(非反显)
3)前景色:
30(黑色)、31(红色)、32(绿色)、 33(黄色)、34(蓝色)、35(洋红)、36(青色)、37(白色)
4)背景色:
40(黑色)、41(红色)、42(绿色)、 43(黄色)、44(蓝色)、45(洋红)、46(青色)、47(白色)
示例:
printf( “\033[1;32;40m 输出绿色字符 \033[0m” )
把程序中printf()代码稍作修改
printf("\033[1;32;40m wys@DESKTOP-2OU3HRV:\033[0m \033[1;34;40m~$\033[0m");
重新编译运行代码
颜色发生了改变。