详解简单的shell脚本 --- 命令行解释器【Linux后端开发】


首先附上完整代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
//命令行解释器
//shell 运行原理:通过让子进程执行命令,父进程等待&&解析命令

//保存完整的命令行字符串 -- 充当缓冲区
#define NUM 1024
char cmd_line[NUM];

//保存切割之后的字符串
#define SIZE 32
char* g_argv[SIZE];

#define SEP " "

int main()
{
    //0.命令行解释器,一定是一个常驻内存的进程 --- 不退出(死循环)
    while(1)
    {
        //1打印出提示信息 -- [wxq@VM-4-9-centos shell]$ 
        printf("[dwr@VM-1-1-test shell]$ ");
        fflush(stdout);
       
        //2.获取用户的键盘输入[输入的是各种指令和选项"ls -a -l"]
        memset(cmd_line, 0, sizeof cmd_line);
        if(fgets(cmd_line, sizeof cmd_line, stdin) == NULL)
        {
            continue;
        }
        //输入的回车键设为\0  ls -a -l \n \0
        cmd_line[strlen(cmd_line)-1]  = '\0';

       // printf("echo:%s\n", cmd_line);   //debug
        
        //3.命令行字符串进行解析 "ls -a -l -s"  --->  "la" "-a" "-l" "-s"
        g_argv[0] = strtok(cmd_line, SEP); //第一次调用,传入原始的字符串

        int index = 1;
        while(g_argv[index++] = strtok(NULL, SEP)); //第二次调用,如果还要分割原始字符串,传入NULL
        
        //简单配置ls的颜色
        int i = 1;
        if(strcmp(g_argv[0], "ls") == 0)
        {
            g_argv[i++] = "--color=auto";
        }
       
        //识别别名 - 主要是测试,一般是有接口的
        if(strcmp(g_argv[0], "ll") == 0)
        {
            g_argv[0] = "ls";
            g_argv[i++] = "-l";
            g_argv[i++] = "--color=auto";
        }


        //debug
//        for(index = 0 ; g_argv[index]; index++)
//        {
//            printf("g_argv[%d]: %s\n", index, g_argv[index]);
//        }

        
        //4.TODO 内置命令:让父进程(shell)自己执行的命令。我们叫做内置命令,内建命令
        //内建命令本质就是shell中的一个函数调用
        if(strcmp(g_argv[0], "cd") == 0) //not child execute; father execute;
        {
            if(g_argv[1] != NULL)
            {
                chdir(g_argv[1]); //cd  cd ..
            }

            continue;
        
         }

        //5.创建子进程进行程序替换
        pid_t id = fork();

        //child
        if(id == 0)
        {
           execvp(g_argv[0],g_argv);
           exit(-1);
        }

        //father
        int status = 0;
        pid_t ret = waitpid(id, &status, 0); //阻塞等待
        if(ret > 0)
        {
            printf("exit code:%d\n",WEXITSTATUS(status));
        }

    }

    return 0;
}

效果:

命令行解释器  

       
shell 运行原理:通过让子进程执行命令,父进程等待&&解析命令

步骤1. 命令行解释器,一定是一个常驻内存的进程 --- 这意味着它是不退出的(死循环)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值