zoukankan      html  css  js  c++  java
  • 十七、文件和目录——minishell(1)

      

      主函数运行要去读取从标准输入或终端上输入的整个命令行,然后再去解析命令行参数,解析出来之后,要将其封装成一个 program,然后再将 program 放入 job 中,然后再去执行 job 中的命令行的内容。

    17.1 job.o

      job.h 文件

     1 #ifndef __JOB_H__
     2 #define __JOB_H__
     3 
     4 typedef struct
     5 {
     6     char **args; //shell 当中输入的命令参数;对应主函数中的 char *argv[] 参数
     7 }Program;
     8 
     9 //作业结构体,表示若干个要执行的参数
    10 typedef struct
    11 {
    12     char         *cmd;
    13     int         progs_num;
    14     Program     *progs;//Program 的结构体指针
    15 }Job;
    16 
    17 extern Job * create_job(char *cmd);
    18 extern void destroy_job(Job *job);
    19 extern Program* create_program(char **arg);//创建一个程序
    20 extern void destroy_program(Program *prog);
    21 extern int add_program(Job *job, Program *prog);//将程序加入到 job 中
    22 
    23 #endif

      job.c 文件

      1 #include "job.h"
      2 #include <malloc.h>
      3 #include <assert.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 #include <stdio.h>
      7 #include <memory.h>
      8 
      9 
     10 /* 根据 commond 命令创建 job */
     11 Job * create_job(char *cmd)
     12 {
     13     Job *job = (Job *)malloc(sizeof(Job));
     14     assert(job != NULL);
     15 
     16     job->cmd = (char *)malloc(sizeof(char) * strlen(cmd));
     17     assert(job->cmd != NULL);
     18 
     19     strcpy(job->cmd, cmd);
     20     job->progs_num = 0;
     21     job->progs = NULL;
     22 
     23     return job;
     24 }
     25 
     26 void destroy_job(Job *job)
     27 {
     28     assert(job != NULL);
     29     free(job->progs);
     30     free(job->cmd);
     31     free(job);
     32 }
     33 
     34 /* 统计命令行参数的个数 */
     35 static int arg_num(char **arg)
     36 {
     37     int i = 0;
     38     char *start = arg[0];
     39 
     40     while(start != NULL) {
     41         i++;
     42         start = arg[i];
     43     }
     44 
     45     return i;
     46 }
     47 
     48 
     49 /*
     50  *     函数功能:    构建一个 program
     51  *     函数参数:
     52  *         @arg:命令行传入的参数
     53  *     返回值:
     54  */
     55 Program* create_program(char **arg)//创建一个程序
     56 {
     57     //在堆当中创建 program 内存块
     58     Program *prog = (Program *)malloc(sizeof(Program));
     59     assert(prog != NULL);
     60 
     61     int counter = arg_num(arg);
     62 
     63     //多 new 一个空间存放 NULL ,所以 counter 要 +1
     64     prog->args = (char **)calloc(counter + 1, sizeof(char *));
     65 
     66     int i;
     67     for(i = 0; i < counter; i++) {
     68         int len = strlen(arg[i]);
     69         prog->args[i] = (char *)malloc(len);
     70         assert(prog->args[i] != NULL);
     71         strcpy(prog->args[i], arg[i]);
     72     }
     73     prog->args[i] = NULL;
     74     return prog;
     75 }
     76 
     77 void destroy_program(Program *prog)
     78 {
     79     assert(prog != NULL);
     80     int i = 0;
     81 
     82     /* 命令行释放 */
     83     while(prog->args[i] != NULL) {
     84         free(prog->args[i]);
     85         i++;
     86     }
     87     free(prog->args);//数组释放
     88     free(prog);
     89 }
     90 
     91 /*    1.通过动态分配创建一个结构体数组
     92  *    2.将 job 中原先的 progs 复制给 ps 结构体数组
     93  *    3.在向 ps 结构体数组中加上新的 prog
     94  *    4.把  job 中原先的 progs 释放掉
     95  *    5.将 job 中的 progs 指向 ps
     96  */
     97 int add_program(Job *job, Program *prog)//将程序加入到 job 中
     98 {
     99     Program *ps = (Program *)malloc(sizeof(Program) * (job->progs_num + 1));//1 为NULL的初始化
    100 
    101     memcpy(ps, job->progs, job->progs_num * sizeof(Program));
    102     ps[job->progs_num++] = *prog;
    103     free(job->progs);
    104     job->progs = ps;
    105 }

      编译成 .o 文件

      gcc -o obj/job.o -Iinclude -c src/job.c

    17.2 命令行参数的解析

    17.2.1 主函数

      mshell.c

      1 #include "job.h"
      2 #include "cmd_func.h"
      3 #include <unistd.h>
      4 #include <string.h>
      5 #include <fcntl.h>
      6 #include <stdlib.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <memory.h>
     10 #include <assert.h>
     11 #include <malloc.h>
     12 
     13 /* shell 中的提示符 */
     14 char *prompt = "mshell > ";
     15 
     16 /* 指定命令行中传递的最大命令行的长度 */
     17 #define MAX_COMMAND_LEN 256
     18 
     19 
     20 /* 对命令行进行解析 */
     21 void parse_cmd(Job *job, char *line)
     22 {
     23     char **args = (char **)malloc(100 * sizeof(char *));//创建的 program 里面的args
     24     assert(args != NULL);
     25 
     26     /* 分割命令行 */
     27     char *cmd = strtok(line, " ");
     28     args[0] = (char *)malloc(strlen(cmd) * sizeof(char)); //第一个参数为命令本身
     29     strcpy(args[0], cmd);
     30 
     31     int i = 1;
     32     char *s;
     33     while((s = strtok(NULL, " ")) != NULL) {
     34         args[i] = (char *)malloc(strlen(s) * sizeof(char));
     35         strcpy(args[i], s);
     36         i++;
     37     }
     38 
     39     //根据  args 创建 program
     40     Program * prog = create_program(args);
     41     add_program(job, prog);
     42 
     43     int j;
     44     for(j = 0; j < i; j++) {
     45         free(args[j]);
     46     }
     47 
     48     free(args);
     49 }
     50 
     51 /* 执行命令 */
     52 void excute_cmd(Job *job)
     53 {
     54     int i;
     55     for(i = 0; i < job->progs_num; i++) {
     56         if(!strcmp(job->progs[i].args[0], "cd")) {
     57             cd_func(&job->progs[i]);
     58             return;
     59         }
     60 
     61         if(!strcmp(job->progs[i].args[0], "pwd")) {
     62             pwd_func(&job->progs[i]);
     63             return;
     64         }
     65 
     66         if(!strcmp(job->progs[i].args[0], "exit")) {
     67             exit_func(&job->progs[i]);
     68             return;
     69         }
     70     }
     71 }
     72 
     73 
     74 int main(int argc, char *argv[])
     75 {
     76     char buff[MAX_COMMAND_LEN];//存放从命令行中输入的整个命令行
     77     memset(buff, 0, MAX_COMMAND_LEN);
     78     ssize_t size = strlen(prompt) * sizeof(char);//提示符占用的总的大小
     79 
     80     write(STDOUT_FILENO, prompt, size);//输出 shell 的提示符
     81 
     82     ssize_t len;
     83     while(1) {
     84         /* 从标准输入读取命令行的内容 */
     85         len = read(STDIN_FILENO, buff, MAX_COMMAND_LEN);
     86         buff[len - 1] = 0; //结束符
     87 
     88         if(strlen(buff) > 0) {//命令行要大于0
     89             Job *job = create_job(buff);//创建 job
     90 
     91             parse_cmd(job, buff); //对命令行进行解析
     92 
     93             excute_cmd(job); // 执行命令
     94             destroy_job(job); // 销毁
     95 
     96         }
     97 
     98         write(STDOUT_FILENO, prompt, size);
     99         memset(buff, 0, MAX_COMMAND_LEN);
    100     }
    101 
    102     return 0;
    103 }

    17.2.2 命令功能函数

      cmd_func.h

     1 #ifndef __CMD_FUNC_H__
     2 #define __CMD_FUNC_H__
     3 
     4 #include "job.h"
     5 
     6 #define BUFF_SIZE_256         256
     7 
     8 
     9 extern void cd_func(Program *prog);
    10 extern void pwd_func(Program *prog);
    11 extern void exit_func(Program *prog);
    12 
    13 #endif

      cmd_func.c

     1 #include "cmd_func.h"
     2 #include <stdio.h>
     3 #include <stdlib.h>
     4 #include <errno.h>
     5 #include "job.h"
     6 #include <fcntl.h>
     7 #include <string.h>
     8 #include <unistd.h>
     9 
    10 /* 切换目录 */
    11 void cd_func(Program *prog)
    12 {
    13     if(chdir(prog->args[1]) < 0) {
    14         perror("cd error");
    15     }
    16 }
    17 
    18 /* 显示当前工作目录路径 */
    19 void pwd_func(Program *prog)
    20 {
    21     char buff[256];
    22     memset(buff, 0, sizeof(buff));
    23 
    24     /* 获取当前工作目录的绝对路径 */
    25     if(getcwd(buff, sizeof(buff)) == NULL) {
    26         perror("pwd error");
    27     }
    28 
    29     printf("%s
    ", buff);
    30 }
    31 
    32 /* 退出 */
    33 void exit_func(Program *prog)
    34 {
    35     exit(0);
    36 }

      编译成.o 文件

      gcc -o obj/cmd_func.o -Iinclude -c src/cmd_func.c

    17.3 编译调试  

      gcc -o bin/mshell -Iinclude obj/*.o src/mshell.c

      

  • 相关阅读:
    在第一段ionic示例的基础上增加底部导航
    我的第一段ionic代码
    angularjs中ng-repeat的使用
    angular中$location读取url信息
    解决jenkins构建job报错“NoClassDefFoundError” in jenkins/scm/RunWithSCM问题
    完全卸载删除gitlab
    centos7端口永久开放方法
    eclipse解决maven编码UTF-8的不可映射字符
    Apache JMeter压力测试实例
    windows下安装setuptools与pip
  • 原文地址:https://www.cnblogs.com/kele-dad/p/9080289.html
Copyright © 2011-2022 走看看