前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >手搓简易shell

手搓简易shell

作者头像
绝活蛋炒饭
发布2024-12-16 16:24:30
发布2024-12-16 16:24:30
5100
代码可运行
举报
文章被收录于专栏:绝活编程学习绝活编程学习
运行总次数:0
代码可运行

1.打印命令行 ,接受命令行输入

命令行就是,“[用户名@主机名 当前目录]$"获取这些信息都存储在Linux内核中的环境变量中,用getenv()函数取出

代码语言:javascript
代码运行次数:0
复制
      #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <string.h>
    4 #include <unistd.h>
    5 #include <sys/types.h>
    6 #include <sys/wait.h>
    7 
    8 #define SIZE 1024
    9 
   10 const char * GetUserName()
   11 { 
   12   char * userName = getenv("USER");
   13   if(userName) return userName;
   14   else return "None";
   15 }
   16 
   17 const char* GetHostName()
   18 {
   19   char *hostname = getenv("HOSTNAME");
   20   if(hostname) return hostname;
   21   else return "None";
   22 
   23 }
   24                                                                                                                                                                   
   25 
   26 const char *GetPWDName()
   27 {
   28       char *hostname = getenv("PWD");
   29       if(hostname) return hostname;
   30       else return "None";
   31 
   32 }
   33 
   34 int Interactive(char out[],int size)
   35 {  
   36    printf("[%s@%s %s]$",GetUserName(),GetHostName(),GetPWDName());
   37    
   38    fgets(out,size,stdin);
   39     out[strlen(out)-1] = '\0';
             return strlen(out);
   41     }

这里是主函数调用它 ,利用他的返回值(输入的字符串长度)如果为零,不进行下一项,重新打印命令行。


2.切割命令行参数 

char* strtok(char* str,const char* delim);

  • 首次调用:它接受两个参数(待分解的字符串、分割符字符串),函数会在str中查找delim中的任意一个字符,一旦找到,就将该字符替换为字符串结束符’\0’,并返回指向当前令牌(分隔符之前的字符串)的指针。
  • 后续调用:在首次调用后,每次调用strtok,应将第一个参数设置为NULL,以便函数从上次分解的位置查找并分解字符串。

这什么是新添加的几个宏和全局变量。 

代码语言:javascript
代码运行次数:0
复制
 int Split(char in[])
 { 
      int i=0;                                                                                                                                                      
      argv[i]=strtok(in,Sep);
      i++;
      while(argv[i++] = strtok (NULL,Sep));//故意把“==”写成“=”
 }

利用stroke函数把字符串分割成一个个以Sep为分割的小字符串 。

验证一下是不是我们想要的结果。


3. 执行命令

代码语言:javascript
代码运行次数:0
复制
 void Execute()
   62 {
   63   pid_t id =fork();
   64   if(id == 0)
   65   {
   66     execvp(argv[0],argv);
   67   }
   68 
   69   int statue = 0;                                                                                                                                                 
   70   pid_t rid = waitpid(id,&statue,0);
   71   if(rid == id)
   72   {
   73     lastcode=WEXITSTATUS(statue);
   74   }
   75 }

将处理好的命令,交给子进程进行进程程序替换。 


4.处理一下内建命令

类似于这种命令,就是子进程去执行,并不能影响到父进程,无法很好的实现命令,所以这种类型的命令需要我们特殊处理一下。

代码语言:javascript
代码运行次数:0
复制
int BuildinCmd()
{
    int ret = 0;
    // 1. 检测是否是内建命令, 是 1, 否 0
    if(strcmp("cd", argv[0]) == 0)
    {
        // 2. 执行
        ret = 1;
        char *target = argv[1]; //cd XXX or cd
        if(!target) target = Home();
        chdir(target);
        char temp[1024];
        getcwd(temp, 1024);
        snprintf(pwd, SIZE, "PWD=%s", temp);
        putenv(pwd);
    }
    else if(strcmp("export", argv[0]) == 0)
    {
        ret = 1;
        if(argv[1])
        {
            strcpy(env, argv[1]);
            putenv(env);
        }
    }
    else if(strcmp("echo", argv[0]) == 0)
    {
        ret = 1;
        if(argv[1] == NULL) {
            printf("\n");
        }
        else{
            if(argv[1][0] == '$')
            {
                if(argv[1][1] == '?')
                {
                    printf("%d\n", lastcode);
                    lastcode = 0;
                }
                else{
                    char *e = getenv(argv[1]+1);
                    if(e) printf("%s\n", e);
                }
            }
            else{
                printf("%s\n", argv[1]);
            }
        }
    }
    return ret;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.打印命令行 ,接受命令行输入
  • 2.切割命令行参数 
  • 3. 执行命令
  • 4.处理一下内建命令
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档