在进行shell的编写之前,我们首先得了解到shell的运行原理,其次才能知道怎么编写shell,接下来我就简单的介绍shell怎么简单的编写吧!
shell执行过程:
1.读取用户从键盘输入的命令(调用read函数);
2.分析命令,以命令名为文件名,并将其他参数改造为系统调用execvp()参数处理所要求的格式;
3.终端进程(shell)调用fork()或者vfork()建立一个子进程(个人建议采用fork());
fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别:
1. fork ():子进程拷贝父进程的数据段,代码段 (共享代码,数据私有)
vfork ( ):子进程与父进程共享数据段
2. fork ()父子进程的执行次序不确定
vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec或exit 之后父进程才可能被调度运行。
3. vfork ()保证子进程先运行,在她调用exec 或exit 之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。
4.子进程依据文件名(命令名)到目录中查找有关文件,将他调入内存,并创建新的文本段,并根据写时拷贝的方式创建相应的数据段,堆栈段;
5当子进程完成处理或者出现异常后,通过调用exit()或者——exit()函数向父进程报告;
6.终端进程调用waitpid()函数等待子进程完成,并对子进程进行回收。
当普通用户成功登录,系统将执行一个称为shell的程序。正是shell进程提供了命令行提示符。作为默认值(TurboLinux系统默认的shell是BASH),对普通用户用“$”作提示符,对超级用户(root)用“#”作提示符。
一旦出现了shell提示符,就可以键入命令名称及命令所需要的参数。shell将执行这些命令。如果一条命令花费了很长的时间来运行,或者在屏幕上产生了大量的输出,可以从键盘上按ctrl+c发出中断信号来中断它(在正常结束之前,中止它的执行)。
当用户准备结束登录对话进程时,可以键入logout命令、exit命令或文件结束符(EOF)(按ctrl+d实现),结束登录。
在Linux中,有一些命令,例如cd是包含在shell内部的命令,还有一些命令,例如cp、mv或rm是存在于文件系统中某个目录下的单独的程序。对于用户而言,没必要关心一个命令是在shell内部还是在shell外部。
shell对于命令的分析过程如下:
- 首先,检查用户输入的命令是否是内部命令,如果不是在检查是否是一个应用程序;
- shell在搜索路径或者环境变量中寻找这些应用程序;
- 如果键入命令不是一个内部命令并且没有在搜索路径中查找到可执行文件,那么将会显示一条错误信息;
- 如果能够成功找到可执行文件,那么该内部命令或者应用程序将会被分解为系统调用传给Linux内核,然后内核在完成相应的工作;
编写一个简单的shell:
在这段小代码中,我们可以先清楚的看到我们首先调用了一个简单的read函数,现在我就先简单介绍一下read函数吧,(通过man查看函数)