• 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);
    }                                                                                                                                    
  • 相关阅读:
    Android开发 使用 adb logcat 显示 Android 日志
    【嵌入式开发】向开发板中烧写Linux系统-型号S3C6410
    C语言 结构体相关 函数 指针 数组
    C语言 命令行参数 函数指针 gdb调试
    C语言 指针数组 多维数组
    Ubuntu 基础操作 基础命令 热键 man手册使用 关机 重启等命令使用
    C语言 内存分配 地址 指针 数组 参数 实例解析
    CRT 环境变量注意事项
    hadoop 输出文件 key val 分隔符
    com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Too many connections
  • 原文地址:https://www.cnblogs.com/muzihuan/p/5291372.html
Copyright © 2020-2023  润新知