• 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);
    }                                                                                                                                    
  • 相关阅读:
    el-select下拉框选项太多导致卡顿,使用下拉框分页来解决
    vue+elementui前端添加数字千位分割
    Failed to check/redeclare auto-delete queue(s)
    周末啦,做几道面试题放松放松吧!
    idea快捷键
    解决flink运行过程中报错Could not allocate enough slots within timeout of 300000 ms to run the job. Please make sure that the cluster has enough resources.
    用.net平台实现websocket server
    MQTT实战3
    Oracle 查看当前用户下库里所有的表、存储过程、触发器、视图
    idea从svn拉取项目不识别svn
  • 原文地址:https://www.cnblogs.com/muzihuan/p/5291372.html
Copyright © 2020-2023  润新知