当前位置: 首页 > news >正文

简易shell

自主实现shell

done,故意写成=,表示先赋值,再判断,分割之后,strtok会返回NULL,刚好让gArgv最后一个元素是NULL,并且while判断结束

Makefile

  1 myshell:myshell.c                                                                                                                                                      
  2   gcc -o $@ $^
  3 .PHONY:clean
  4 clean:
  5   rm -f myshell

myshell.c

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<sys/types.h>
  4 #include<sys/wait.h>
  5 #include<stdlib.h>
  6 #include<string.h>
  7 #include<errno.h>
  8 
  9 #define SIZE 512
 10 #define ZERO '\0'
 11 #define SEP " "
 12 #define NUM 32
 13 #define SkipPath(p) do{p += (strlen(p) - 1);while(*p != '/') p--;}while(0)
 14 
 15 char cwd[SIZE*2];
 16 char *gArgv[NUM];
 17 int lastcode = 0;
 18 void Die()
 19 {
 20     exit(1);
 21 }
 22 
 23 const char *GetHome()
 24 {
 25     const char *home = getenv("HOME");                                                                                                                                 
 26     if(home == NULL) return "/";
 27     return home;
 28 }
 29 const char *Getusername()
 30 {
 31     const char *name = getenv("USER");
 32     if(name == NULL) return "None";
 33     return name;
 34 }
 35 const char *Gethostname()
 36 {                                                                                                                                                                      
 37     const char *hostname = getenv("HOSTNAME");
 38     if(hostname == NULL) return "None";
 39     return hostname;
 40 }
 41 const char *Getcwd()
 42 {
 43     const char *cwd = getenv("PWD");
 44     if(cwd == NULL) return "None";
 45     return cwd;
 46 }
 47 
 48 void makecommandline()
 49 {
 50     char line[SIZE];
 51     const char *username = Getusername();
 52     const char *hostname = Gethostname();
 53     const char *cwd = Getcwd();
 54                                                                                                                                                                        
 55     SkipPath(cwd);
 56     snprintf(line, sizeof(line), "[%s@%s %s] love:", username, hostname, strlen(cwd) == 1 ? "/" : cwd + 1);
 57     printf("%s", line);
 58     fflush(stdout);
 59 }
 60 
 61 int Getusercommand(char command[], size_t n)
 62 {
 63     char *s = fgets(command, n, stdin);
 64     if(s == NULL) return -1;
 65 
 66     command[strlen(command) - 1] = ZERO;
 67     return strlen(command);
 68 }
 69 
 70 void SplitCommand(char command[], size_t n)
 71 {
 72     (void)n;
 73     gArgv[0] = strtok(command, SEP);
 74     int index = 1;
 75     while((gArgv[index++] = strtok(NULL, SEP)));                                                                                                                       
 76 }
 77 void ExecuteCommand()
 78 {
 79     pid_t id = fork();
 80     if(id < 0) Die();
 81     else if(id == 0)
 82     {
 83         //child
 84         execvp(gArgv[0], gArgv);
 85         exit(errno);
 86     }
 87     else 
 88     {
 89         //father
 90         int status = 0;
 91         pid_t rid = waitpid(id, &status, 0);
 92         if(rid > 0)
 93         {
 94             lastcode = WEXITSTATUS(status);
 95             if(lastcode != 0) printf("%s:%s:%d\n", gArgv[0], strerror(lastcode), lastcode);
 96         }
 97     }
 98 }
 99 
100 void Cd()
101 {
102     const char *path = gArgv[1];
103     if(path == NULL) path =GetHome();
104 
105     chdir(path);                                                                                                                                                       
106     //刷新环境变量
107     char temp[SIZE*2];
108     getcwd(temp, sizeof(temp));
109     snprintf(cwd, sizeof(cwd), "PWD=%s", temp);
110     putenv(cwd);
111 }
112 int CheckBuildin()
113 {
114     int yes = 0;
115     const char *enter_cmd = gArgv[0];
116     if(strcmp(enter_cmd, "cd") == 0)
117     {
118         yes = 1;
119         Cd();
120     }
121     else if(strcmp(enter_cmd, "echo") == 0 && strcmp(gArgv[1], "$?") == 0)
122     {
123         yes = 1;
124         printf("%d\n", lastcode);
125         lastcode = 0;
126     }
127 
128     return yes;
129 }
130 int main()
131 {
132     int quit = 0;                                                                                                                                                      
133     while(!quit)
134     {
135         makecommandline();
136 
137         char usercommand[SIZE];
138         int n = Getusercommand(usercommand, sizeof(usercommand));
139         if(n <= 0) return 1;
140 
141         SplitCommand(usercommand, sizeof(usercommand));
142         
143         n = CheckBuildin();
144         if(n) continue;
145         ExecuteCommand();
146     }
147     
148     return 0;
149 }

相关文章:

  • Python深浅拷贝
  • mysql 查询进程查看并释放
  • 存储过程在高并发环境下的重要性
  • await func().catch()和try{ func() }.catch(),两种写法,有什么区别
  • 设计模式之工厂模式的优缺点
  • NLP 与常见的nlp应用
  • AI在工业自动化中的应用与挑战
  • 麦科信新品发布,8MHz,300Arms高频交直流电流探头CP3008
  • Linux驱动开发实战之SRIO驱动(二)基于Tsi721驱动
  • 分布式中间件:RabbitMQ确认消费机制
  • QT网页显示的几种方法及对比
  • 计算机网络精讲day1——计算机网络的性能指标(上)
  • 【大坐标处理】
  • MyBatis plus详解
  • 使用BootStrap 3的原创的模态框组件,没法弹出!估计是原创的bug
  • day-110 下降路径最小和 II
  • filebeat和logstash区别
  • reCAPTCHA 打码平台
  • CCBCISCN复盘
  • Ubuntu检查并启用 Nginx 的stream模块或重新安装支持stream模块的Nginx
  • 深入贯彻中央八项规定精神学习教育中央第一指导组指导督导河北省见面会召开
  • 明天起,沪苏湖高铁、杭温高铁推出13款新型票制产品
  • 【社论】三个“靠谱”为市场注入确定性
  • 8小时《大师与玛格丽特》:长度可以是特点,但不是价值标准
  • 央行:5月8日起,下调个人住房公积金贷款利率0.25个百分点
  • 人民日报评论:莫让“胖东来们”陷入“棒杀”“捧杀”泥潭