浅析shell的工作原理

本文介绍了Linux中的shell作为命令解释器的角色,详细阐述了shell如何读取并执行用户命令,包括内部命令和外部命令的处理过程,以及shell的执行流程,如fork、execve和wait。同时,还提及了编写简单shell的实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 本章我们的内容将会介绍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

/*************************************************************************
    > File Name: test.c
    > Author: LZH
    > Mail: www.597995302@qq.com 
    > Created Time: 20170213日 星期一 062823************************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>


int main()
{
    pid_t id=fork();
    printf("Load MyShell\n");
    char buf[1024];
    ssize_t Len;
    char* Argv[10];
    int i=0;
    if(id==0){
            while (1)
            {
                //child
                printf("[lzh@localhost MyShell]#");
                fflush(stdout);   //flush buf
                Len = read(0, buf, 1024);
                if (Len>0)
                {//read Success
                    buf[Len - 1] = '\0';
                    printf("Debug:%s\n", buf);
                    int count = 0;
                    char* Start;
                    for (Start = buf; *Start != '\0'; Start++)
                    {
                        Argv[count++] = Start;
                        while (*Start != ' '&&*Start != '\0')
                        {
                            Start++;
                        }
                        if (*Start == '\0')
                        {
                            break;
                        }
                        *Start = '\0';      //*Start==' ',replace 
                    }
                    printf("count:%d\n", count);
                    Argv[count] = NULL;
                    for (i = 0; Argv[i] != NULL; i++)
                    {
                        printf("%d,Debug:%s\n", i, Argv[i]);
                    }
                    execvp(Argv[0], Argv);
                    //  printf("Error\n");
                    //  exit(1);
                }
                else
                {//read error ,finish now cycle
                    perror("Read Error!\n");
                    continue;
                }
                printf("\n");
            }
    }
    else{
            //father
            sleep(1);
            printf("I am father,pid:%d,ppid:%d\n",getpid(),getppid());
            wait(NULL);
    }
    return 0;
}

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


相关文章:

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值