浅析shell的工作原理

r囧r小猫 2022-07-12 05:53 363阅读 0赞
  • 本章我们的内容将会介绍Linux中的命令解释器shell的工作原理
  • 我们还会编写一个简单的shell

什么是shell?

Linux系统的shell相当于操作系统的“一层外壳”,它是命令语言解释器,它为用户提供了使用操作系统的接口,它不属于内核,而是在内核之外以用户态方式运行。它的基本功能是解释并执行用户打入的各种命令,实现用户与Linux内核的接口。
在启动Linux系统后,内核会为每个终端用户建立一个进程去执行shell解释程序,它的执行过程遵循以下步骤:

1.读取用户由键盘输入的命令;
2.对命令进行分析,以命令名为文件名,并将其他参数改造为系统调用execve()参数处理所要求的格式;
3.终端进程(shell)调用fork()或者vfork()建立一个子进程;
4.子进程根据文件名(命令名)到目录中查找有关文件,将他调入内存,并创建新的文本段,并根据写时拷贝的方式创建相应的数据段、堆栈段;
5.当子进程完成处理或者出现异常后,通过exit()或_exit()函数向父进程报告;
6.终端进程调用wait函数来等待子进程完成,并对子进程进行回收;


shell对输入的命令的分析

在Linux中,有一些命令,例如cd是包含在shell内部的命令,还有一些命令,例如cp、mv或rm是存在于文件系统中某个目录下的单独的程序。对于用户而言,没必要关心一个命令是在shell内部还是在shell外部。
shell对于命令的分析过程如下:

  1. 首先,检查用户输入的命令是否是内部命令,如果不是在检查是否是一个应用程序;
  2. shell在搜索路径或者环境变量中寻找这些应用程序;
  3. 如果键入命令不是一个内部命令并且没有在搜索路径中查找到可执行文件,那么将会显示一条错误信息;
  4. 如果能够成功找到可执行文件,那么该内部命令或者应用程序将会被分解为系统调用传给Linux内核,然后内核在完成相应的工作;

编写一个简单的shell

  1. /*************************************************************************
  2. > File Name: test.c
  3. > Author: LZH
  4. > Mail: www.597995302@qq.com
  5. > Created Time: 2017年02月13日 星期一 06时28分23秒
  6. ************************************************************************/
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <sys/types.h>
  10. #include <sys/wait.h>
  11. #include <stdlib.h>
  12. int main()
  13. {
  14. pid_t id=fork();
  15. printf("Load MyShell\n");
  16. char buf[1024];
  17. ssize_t Len;
  18. char* Argv[10];
  19. int i=0;
  20. if(id==0){
  21. while (1)
  22. {
  23. //child
  24. printf("[lzh@localhost MyShell]#");
  25. fflush(stdout); //flush buf
  26. Len = read(0, buf, 1024);
  27. if (Len>0)
  28. {
  29. //read Success
  30. buf[Len - 1] = '\0';
  31. printf("Debug:%s\n", buf);
  32. int count = 0;
  33. char* Start;
  34. for (Start = buf; *Start != '\0'; Start++)
  35. {
  36. Argv[count++] = Start;
  37. while (*Start != ' '&&*Start != '\0')
  38. {
  39. Start++;
  40. }
  41. if (*Start == '\0')
  42. {
  43. break;
  44. }
  45. *Start = '\0'; //*Start==' ',replace
  46. }
  47. printf("count:%d\n", count);
  48. Argv[count] = NULL;
  49. for (i = 0; Argv[i] != NULL; i++)
  50. {
  51. printf("%d,Debug:%s\n", i, Argv[i]);
  52. }
  53. execvp(Argv[0], Argv);
  54. // printf("Error\n");
  55. // exit(1);
  56. }
  57. else
  58. {
  59. //read error ,finish now cycle
  60. perror("Read Error!\n");
  61. continue;
  62. }
  63. printf("\n");
  64. }
  65. }
  66. else{
  67. //father
  68. sleep(1);
  69. printf("I am father,pid:%d,ppid:%d\n",getpid(),getppid());
  70. wait(NULL);
  71. }
  72. return 0;
  73. }

测试结果如下:
这里写图片描述


相关文章:

进程管理之程序替换:
http://blog.csdn.net/bit_clearoff/article/details/55051580

进程管理之创建进程、进程等待、终止进程:
http://blog.csdn.net/bit_clearoff/article/details/54603375

发表评论

表情:
评论列表 (有 0 条评论,363人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Kafka原理浅析

    1.Kafka简介             Kafka 是一个消息系统,原本开发自 LinkedIn,用作 LinkedIn 的活动流(Activity Stream)和运营