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

Linux小程序: 手写自己的shell

注意: 本文章只是为了理解shell内部的工作原理, 所以并没有完成shell的所有工作, 只是完成了shell里的一小部分工作

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h> 
#include <sys/wait.h>#define LEFT "["
#define RIGHT "]"
#define END "#"
#define SPLIT " "
#define LINE_SIZE 1024
#define ARGV_SIZE 32
#define EXIT_CODE 66
#define PWD_SIZE 100int lastexit = 0;
int quit = 0;
char pwd[PWD_SIZE];const char* getusername() {return getenv("USER");
}const char* mygethostname() {return getenv("HOSTNAME");
}void getpwd() {getcwd(pwd, PWD_SIZE);
}void display() {getpwd();printf(LEFT"%s@%s %s"RIGHT""END" ", getusername(), mygethostname(), pwd);
}void getinput(char* cline, int size) {char* s = fgets(cline, size, stdin);assert(s != NULL);cline[strlen(cline) - 1] = '\0';//printf("%s\n", cline);
}int split(char* cline, char* argv[]) {int i = 0;//printf("%s", cline);argv[i ++] = strtok(cline, SPLIT);while (argv[i ++] = strtok(NULL, SPLIT));return i - 1;
}void normalExe(char* argv[]) {extern char** environ;pid_t id = fork();if (id < 0) {perror("fork");//continue;} else if (id == 0) {// childexecvpe(argv[0], argv, environ);exit(EXIT_CODE);}// fatherint status = 0;pid_t ret = waitpid(id, &status, 0);//  if (ret > 0) printf("wait success pid: %d\n", ret);if (ret > 0) lastexit = WEXITSTATUS(status);
}int neijian(char* argv[], int argc) {if (argc == 2 && strcmp(argv[0], "cd") == 0) {chdir(argv[1]);getpwd();return 1;}return 0;
}int main() {//int quit = 0;char cline[LINE_SIZE];char* argv[ARGV_SIZE] = { NULL };extern char** environ;while (!quit) {display();getinput(cline, LINE_SIZE);int tt = split(cline, argv);if (tt == 0) continue;//printf("%d\n", tt);/*int i = 0;for (i = 0; argv[i]; ++ i)printf("%s ", argv[i]);printf("\n");*/// 内建命令执行//内建命令本质上就是shell内部的一个函数int n = neijian(argv, tt);//printf("%d\n", n); //普通命令执行if (!n) normalExe(argv);}return 0;
}

相关文章:

  • LabVIEW比例流量阀自动测试系统
  • Eclipse+Java+Swing实现斗地主游戏
  • 散热风扇220v交流12v直流12038轴流风机配电箱机柜散热风扇15050
  • Rust教程:How to Rust-基本类型
  • 探索数据库mysql--------------mysql主从复制和读写分离
  • 电脑关机速度很慢怎么解决?
  • L3-016 二叉搜索树的结构
  • LeetCode //C - 436. Find Right Interval
  • MySQL进阶-----索引的语法与SQL性能分析
  • 【Python百日进阶-Web开发-Peewee】Day290 - Peewee 的扩展(十)架构迁移(下)/ 映射
  • Unity 学习日记 12.小球撞击冰块游戏
  • RabbitMQ介绍
  • 【WPF应用16】WPF如何让Canvas上的元素响应鼠标点击事件?
  • 企业产品网络安全建设日志0328
  • 单源最短路径
  • [译] 怎样写一个基础的编译器
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 【知识碎片】第三方登录弹窗效果
  • 2017-09-12 前端日报
  • css的样式优先级
  • gcc介绍及安装
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • input实现文字超出省略号功能
  • iOS 颜色设置看我就够了
  • js如何打印object对象
  • js算法-归并排序(merge_sort)
  • MobX
  • node-glob通配符
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • SSH 免密登录
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 关于List、List?、ListObject的区别
  • 简单数学运算程序(不定期更新)
  • 类orAPI - 收藏集 - 掘金
  • 三分钟教你同步 Visual Studio Code 设置
  • 什么是Javascript函数节流?
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 我的zsh配置, 2019最新方案
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • # 飞书APP集成平台-数字化落地
  • #、%和$符号在OGNL表达式中经常出现
  • (03)光刻——半导体电路的绘制
  • (2022 CVPR) Unbiased Teacher v2
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (原)Matlab的svmtrain和svmclassify
  • **PHP二维数组遍历时同时赋值
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .net Application的目录
  • .NET开源快速、强大、免费的电子表格组件
  • .NET企业级应用架构设计系列之结尾篇
  • .vue文件怎么使用_vue调试工具vue-devtools的安装