zoukankan      html  css  js  c++  java
  • linux高编进程------支持外部命令的shell实现(glob、strsep、fork)

    简单实现一个可以支持外部命令的shell:

    /*****************************
     *功能:实现一个简单的shell
     *终端:./shell
     *      可以输入pwd等外部命令测试
     * **************************/
    
    /*******包含头文件********/
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <string.h>
    #include <glob.h>
    
    /*******提取DELIMS分隔符*******/
    #define DELIMS  " 	
    "
    
    /********创建命令结构体(方便扩展)**********/
    struct cmd_st
    {
        glob_t globres ;
    };
    
    /********打印终端的提示*********/
    static void prompt(void)
    {
        printf("mysh-0.1$ ");
    }
    /***********************************
     *功能:解析终端输入的命令行
     *      参数:line:从终端获取的命令行
     *            res:解析的命令行(回填)
     * ********************************/
    static void parse(char *line,struct cmd_st *res)
    {
        char *tok ;
        int i = 0 ;
        while(1)
        {
            //1.从终端截取命令字符串(line为指向欲分割的字符串,DELIM为分隔符,函数将返回分隔符前面的字符串,tok将指向分隔符之后的字符串)
            tok = strsep(&line,DELIMS);
            //2.如果解析失败跳出循环
            if(tok == NULL)
                break ;
            //3.当多个分割符连续可能出现空串则继续
            if(tok[0] == '')
                continue ;
            /*********************************************************
             * 4.取得的每个字符串都应该保存(由于命令长度不确定,所以一定要变长)
             *  所以用glob中的gl_pathv存储
             *  flag:GLOB_NOCHECK:如果没有任何内容匹配tok,返回tok
             *        GLOB_APPEND:第一次不追加,以后追加(不加会覆盖)
             *  存储结果放到res->globres中
             *  ******************************************************/
            glob(tok,GLOB_NOCHECK | GLOB_APPEND*i ,NULL,&res->globres);
            i = 1 ;
        }
    }
    
    int main()
    {
        //1.如果使用getline,一定要初始化
        char *linebuf = NULL ;
        size_t linebuf_size = 0 ;
    
        struct cmd_st cmd ;
        pid_t pid ;
    
        while(1)
        {   //2.打印终端
            prompt();
            //3.获取字符串
            if(getline(&linebuf ,&linebuf_size,stdin) < 0)
                break;
            //4.解析字符串,结果放到cmd.globres.gl_pathv中
            parse(linebuf,&cmd);
    
            if(0){}//内部命令
            else
            {   //5.外部命令:创建子进程
                pid = fork();
                if(pid < 0)
                {
                    perror("fork()");
                    exit(1);
                }
                //6.子进程用新进程替换当前进程
                if(pid == 0)
                {
                    execvp(cmd.globres.gl_pathv[0],cmd.globres.gl_pathv);
                    perror("execvp");
                    exit(1);
                }
                else
                {   //7.父进程收尸
                    wait(NULL);
                }
            }
        }
        exit(0);
    }                                                                                                                                    
  • 相关阅读:
    Day00课程前奏
    bootstrap前端框架
    html5标签
    js个人笔记
    css88
    小说拆分器
    什么是依赖注入
    与Java的约会
    Dom4J两种节点添加方法比较
    nodejs + typescript + koa + eslint + typescript eslint + prettier + webstorm
  • 原文地址:https://www.cnblogs.com/muzihuan/p/5291372.html
Copyright © 2011-2022 走看看