实现简易版shell
操作系统小组作业,实现一个简易shell,shell实现了下列命令
exit------退出终端命令
clr-------清屏命令
time-----时间命令
myshell----欢迎命令
quit-----终止命令
pwd-----路径命令
cat-----查看文件命令
help---帮助命令
help [参数]---查看某个具体的命令的注释
ls -l-----查看目录下的文件命令
只实现了简单的几个命令,仅做参考,代码如下
#include<bits/stdc++.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include<pwd.h>
#include<time.h>
#include<dirent.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <grp.h>
#include <sys/wait.h>
#include<memory.h>
using namespace std;
#define MAX_LINE 80
#define MAX_NAME_LEN 50
#define MAX_PATH_LEN 1000
int cmd_cnt;
char *cmd_array[MAX_LINE/+];
string st;
void mytime(){
int weekday;
int month;
time_t tvar;
struct tm *tp;
time(&tvar);
tp=localtime(&tvar);//获取本地时间
weekday=tp->tm_wday;
switch(weekday){//根据不同的值打印不同的星期
case :
printf("Mon ");
break;
case :
printf("Tues ");
break;
case :
printf("Wed ");
break;
case :
printf("Thur ");
break;
case :
printf("Fri ");
break;
case :
printf("Sat ");
break;
case :
printf("Sun ");
break;
default:
break;
}
month=+tp->tm_mon;//必须要加1,经过查阅资料:tm_mon比实际的值少了1
switch(month){//根据不同的值打印月份名
case :
printf("Jan ");
break;
case :
printf("Feb ");
break;
case :
printf("Mar ");
break;
case :
printf("Apr ");
break;
case :
printf("May ");
break;
case :
printf("Jun ");
break;
case :
printf("Jul ");
break;
case :
printf("Aug ");
break;
case :
printf("Sep ");
break;
case :
printf("Oct ");
break;
case :
printf("Nov ");
break;
case :
printf("Dec ");
break;
default:
break;
}
printf("%d ",tp->tm_mday);//日期
printf("%d:",tp->tm_hour);//小时
printf("%d:",tp->tm_min);//分钟
printf("%d ",tp->tm_sec);//秒
printf("CST ");//CST,意思是China Standard Time
printf("%d\n",+tp->tm_year);//必须加上1900,返回的值并不是完整的年份,比真实值少了1900
}
void welcome(){
//如下是欢迎信息
//为了是程序更友好,加入了颜色
//颜色是紫色,背景色与shell相同
printf("\e[32mwelcome to myshell\e[0m\n");
printf("\e[32mit's a Lunix-like shell program made by us\e[0m\n");
printf("\e[32mhope you have a good time with it :-)\e[0m\n");
}
void mypwd(){
char pathname[MAX_PATH_LEN];
if(getcwd(pathname,MAX_PATH_LEN)){//获取路径名
printf("%s\n",pathname);
}
else{//如果出错
perror("myshell: getcwd");//报错
exit();
}
} void myquit(){
printf("Thanks for your using,bye-bye!\n");
sleep();//暂停1s,看上去视觉效果好一些
exit();
}
void exit(){
exit();
}
void myclr(){
cout << "\033[2J";
cout << "\033[H"; } void printprompt(){//实现命令提示符 char hostname[MAX_NAME_LEN];
char pathname[MAX_PATH_LEN];
struct passwd *pwd;
pwd=getpwuid(getuid());
gethostname(hostname,MAX_NAME_LEN);
printf("\e[34m%s@%s:\e[0m",pwd->pw_name,hostname); printf("$"); } //*****************************************************获得文件权限属性
void getPower(mode_t mod)
{
for(int n=; n>=; n--)
{
if(mod&(<<n))//移位运算,1左移位n位
{
switch(n%)
{
case :
printf("r");
break;
case :
printf("w");
break;
case :
printf("x");
break;
default:
break;
}
}
else
{
printf("-");
}
}
} void cat(string filename){
ifstream fin( filename);
char str[];
while ( fin.getline(str,) )
{
cout << str << endl;
}
} void ls(string allstr,string substr){ /******************************ls*************************
*
*dirName[] :store single filename
*dir :point to currnt directory
*rent :指针变量
*st :文件基本操作
**********************************************************/ struct stat st;
char dirName[]; DIR *dir;
struct dirent *rent;//struct
dir = opendir("."); if(allstr== "ls"){ if(dir != NULL)
{
while((rent=readdir(dir)))
{ strcpy(dirName,rent->d_name);
if (dirName[]!='.' && dirName)
{
cout << dirName<<'\t';
}
}
} cout << endl;
}
else if(dir == NULL)
{
cout << "*****empty*****"<<endl;
}
else if(allstr != "ls -l")
{
cout << substr+": "+ "unrecognized option "+"'"+allstr.substr(substr.length())+"'"<<endl;
cout << "Try 'ls -l' "<<endl;
} /******************************************ls -l*************************/ else if(allstr == "ls -l")
{
while( rent = readdir(dir) )
{
strcpy(dirName,rent->d_name);
if (dirName[]!='.' && dirName)
{
if(- != stat(rent->d_name, &st) )//get fileInfomation from filename p->d_name and save it in structure stat
{
getPower(st.st_mode); //get r-w-d
cout <<" "<<st.st_nlink<<" ";//get number of file links
cout <<" "<<getpwuid(st.st_uid)->pw_name<<" ";//owner name
cout <<getgrgid(st.st_gid)->gr_name<<'\t'; //group name
cout << st.st_size<<'\t'; //get total size , in bytes //printf 12 char and align = left
printf("%.12s ",+ctime(&st.st_mtime)); //the last time of changing file
cout << dirName;
cout << endl;
}
}
}
} closedir(dir);
} //****************************************************获得输入字符
string strInput()
{
string str;
string res;
char c;
while( (c = getchar()) != '\n')
str += c; vector<string> arr;
istringstream istr(str);
string word;
while(istr>>word) {
arr.push_back(word);//添加元素到尾部
} for(int i=; i<arr.size(); i++) {
if(i != arr.size() - )
res += arr[i]+" ";
else
res += arr[i];
} return res;
}
///////////////////////////////////////////////////////////help命令
void print_manual(){
printf("welcome to the manual of myshell, hope it's useful for you\n");
printf("the following are the BUILT-IN commands supported by myshell\n");
printf("\n"); printf("exit: exit quit the shell directly\n");
printf("clr: clr clear the screen\n");
printf("time: time show the current time in an elegant format\n");
printf("myshell: myshell [filename] execute a batchfile\n");
printf("quit: quit quit the shell with thank-you\n");
printf("pwd: pwd print the current working directory\n");
printf("help: help/help [command] show the manual of help/get help info of a sepcified command\n"); }
void print_cmdinfo(string cmdname){ if(cmdname=="exit"){
printf("usage:quit the shell directly\n");
printf("options descriptions\n");
printf("none see the manual,plz\n");
}
else if(cmdname=="pwd"){
printf("usage:print the current working directory\n");
printf("options descriptions\n");
printf("none see the manual,plz\n");
}
else if(cmdname=="time"){
printf("usage:show the current time in an elegant format\n");
printf("options descriptions\n");
printf("none see the manual,plz\n");
}
else if(cmdname=="clr"){
printf("usage:clear screen\n");
printf("options descriptions\n");
printf("none see the manual,pls\n");
}
else if(cmdname=="myshell"){
printf("usage:execute a batchfile\n");
printf("options descriptions\n");
printf("none see the manual,plz\n");
}
else if(cmdname=="help"){
printf("usage:show the manual of help/get help info of a sepcified command\n");
printf("options descriptions\n");
printf("none see the manual,plz\n");
}
else if(cmdname=="quit"){
printf("usage:quit the shell with thank-you information\n");
printf("options descriptions\n");
printf("none see the manual,plz\n");
}
else {//如果有错
printf("myshell: help: Invalid use of help command\n");//打印提示信息
} }
void myhelp(){
if(cmd_cnt==){//如果是不带参数的help
print_manual();//调用子函数print_manual打印用户帮助手册
}
else if(cmd_cnt==){//如果格式是"help [command]"
print_cmdinfo(st);//打印单个命令的帮助信息
} }
void help(string str){
if(str=="help"){
cmd_cnt=;
}
else if(str.length()>){ cmd_cnt=;
st=str.substr(,str.length());
} myhelp();
}
/////////////////////////////////////////////////////////////////////////////////
int main()
{
string n;
string str1; //first str !=include space
string str2; while(true){
printprompt();
n=strInput(); istringstream istr(n);
istr >> str1>>str2; if(str1 == "ls"){
ls(n,str1);
continue;
}
if(n=="exit")//退出
exit();
else if(n=="clr"){
myclr();
}
else if(n=="time")
{
mytime();
}
else if(n=="myshell")
{
welcome();
}
else if(n=="quit")
{
myquit();
}
else if(n=="pwd")
{
mypwd();
}
else if(str1 == "cat"){
cat(str2);
}
else if(str1=="help"){
help(n);
}
else
cout << "invaild command" << endl; } return ;
}
如果需要的话,下面链接里面有我对该代码的部分不常见的函数和结构体的注释,如需要的可以看一下
https://files-cdn.cnblogs.com/files/henuliulei/shellzhushi.zip
实现简易版shell的更多相关文章
- 单片机实现简易版shell的方法和原理
Rt-thread 中有一个完整的finsh(shell )系统,使用串口做命令行输入输出.但是想要用这个炫酷的工具就必须要上rtthread系统,或者花大力气将其移植出来.于是我就自己写了一个类似于 ...
- .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”
FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ...
- MVC 验证码实现( 简易版)
现在网站上越来越多的验证码,使用场景也是越来越多,登陆.注册.上传.下载...等等地方,都有可能大量使用到验证码,那么制作验证码到底有多简单呢?我们一起来看下最简易版的验证码实现过程- 验证码的基本步 ...
- 简易版自定义BaseServlet
这几天在学Java Web,一直在思考Servlet重用的问题,就用java的反射机制实现自定义的简易版BaseServlet; 该方式有点像struts2 利用映射获取前端的参数.有兴趣的同学可以自 ...
- 简易版的TimSort排序算法
欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. 简易版本TimSort排序算法原理与实现 TimSort排序算法是Python和Ja ...
- html5 canvas简易版捕鱼达人游戏源码
插件描述:html5利用canvas写的一个js版本的捕鱼,有积分统计,鱼可以全方位移动,炮会跟着鼠标移动,第一次打开需要鼠标移出背景图,再移入的时候就可以控制炮的转动,因为是用的mouseover触 ...
- Python写地铁的到站的原理简易版
Python地铁的到站流程及原理(个人理解) 今天坐地铁看着站牌就莫名的想如果用Python写其工作原理 是不是很简单就小试牛刀了下大佬们勿喷纯属小弟个人理解 首先来看看地铁上显示的站牌如下: 就想这 ...
- MVC5+EF6 简易版CMS(非接口) 第四章:使用业务层方法,以及关联表解决方案
目录 简易版CMS后台管理系统开发流程 MVC5+EF6 简易版CMS(非接口) 第一章:新建项目 MVC5+EF6 简易版CMS(非接口) 第二章:建数据模型 MVC5+EF6 简易版CMS(非接口 ...
- C+命令行+方向键=简易版扫雷
前言: 想起来做这个是因为那时候某天知道了原来黑框框里面的光标是可以控制的,而且又经常听人说起这个,就锻炼一下好了. 之前就完成了那1.0的版本,现在想放上来分享却发现有蛮多问题的,而且最重要的是没什 ...
随机推荐
- 【题解】P2602[JZOI2010]数字计数
[题解][P2602ZJOI2010]数字计数 乍看此题,感觉直接从数字的位上面动手,感觉应该很容易. 但是仔细看数据范围,发现如果不利用计数原理,肯定会超时,考虑数码出现的特征: \(A000\)到 ...
- Activity设置style透明后与SurfaceView合用引发的无形命案
近期搞视频通话,SurfaceView是不可缺少的,因为启动视频要载入一些资源,比較耗时.会有1.2s黑屏的现象,为了改善用户体验,我们须要设置Activity的Theme为透明风格(QQ 也是如此) ...
- 关于TensorFlow若干问题的汇总
1.TensorFlow中padding的两种类型SAME和VALID 简而言之:padding='SAME'表示采用在两端填充0进行补全的方式,左右填充0的个数可能并不同. padding='VAL ...
- sys添加路径
暂时更改sys.path sys.path.append()
- Swift 烧脑体操(三) - 高阶函数
前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说更加困 ...
- Quartz Job scheduling 基础实现代码
Quartz 集成在 SpringBoot 中分为 config.task.utils.controller 和 MVC 的三层即 controller.service.dao 和 entity. c ...
- 郝健: Linux内存管理学习笔记-第2节课【转】
本文转载自:https://blog.csdn.net/juS3Ve/article/details/80035753 摘要 slab./proc/slabinfo和slabtop 用户空间mallo ...
- CentOS 7 设置自定义开机启动,添加自定义系统服务
详细文档,http://www.linuxidc.com/Linux/2015-04/115937.htm 摘自: http://www.centoscn.com/CentOS/config/2015 ...
- FastJson 输出值 首字母大小写问题
解决方案: 1. 如果你的项目由多个模块且为分布式部署, 则可考虑使用设置System.property 2. 一般只是极少数的代码出现此情况, 那么建议直接在你的单例Service初始化时, 在静态 ...
- LoadRunner监控图表与配置(三)对系统与网络资源进行监控
1.Windows可监控的性能计数器 2.UNIX可监控的性能计数器 3.性能计数器信息说明 Windows 性能对象 计数器 数值说明 System %Total Processor Time 系统 ...