操作系统小组作业,实现一个简易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的更多相关文章

  1. 单片机实现简易版shell的方法和原理

    Rt-thread 中有一个完整的finsh(shell )系统,使用串口做命令行输入输出.但是想要用这个炫酷的工具就必须要上rtthread系统,或者花大力气将其移植出来.于是我就自己写了一个类似于 ...

  2. .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”

    FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ...

  3. MVC 验证码实现( 简易版)

    现在网站上越来越多的验证码,使用场景也是越来越多,登陆.注册.上传.下载...等等地方,都有可能大量使用到验证码,那么制作验证码到底有多简单呢?我们一起来看下最简易版的验证码实现过程- 验证码的基本步 ...

  4. 简易版自定义BaseServlet

    这几天在学Java Web,一直在思考Servlet重用的问题,就用java的反射机制实现自定义的简易版BaseServlet; 该方式有点像struts2 利用映射获取前端的参数.有兴趣的同学可以自 ...

  5. 简易版的TimSort排序算法

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. 简易版本TimSort排序算法原理与实现 TimSort排序算法是Python和Ja ...

  6. html5 canvas简易版捕鱼达人游戏源码

    插件描述:html5利用canvas写的一个js版本的捕鱼,有积分统计,鱼可以全方位移动,炮会跟着鼠标移动,第一次打开需要鼠标移出背景图,再移入的时候就可以控制炮的转动,因为是用的mouseover触 ...

  7. Python写地铁的到站的原理简易版

    Python地铁的到站流程及原理(个人理解) 今天坐地铁看着站牌就莫名的想如果用Python写其工作原理 是不是很简单就小试牛刀了下大佬们勿喷纯属小弟个人理解 首先来看看地铁上显示的站牌如下: 就想这 ...

  8. MVC5+EF6 简易版CMS(非接口) 第四章:使用业务层方法,以及关联表解决方案

    目录 简易版CMS后台管理系统开发流程 MVC5+EF6 简易版CMS(非接口) 第一章:新建项目 MVC5+EF6 简易版CMS(非接口) 第二章:建数据模型 MVC5+EF6 简易版CMS(非接口 ...

  9. C+命令行+方向键=简易版扫雷

    前言: 想起来做这个是因为那时候某天知道了原来黑框框里面的光标是可以控制的,而且又经常听人说起这个,就锻炼一下好了. 之前就完成了那1.0的版本,现在想放上来分享却发现有蛮多问题的,而且最重要的是没什 ...

随机推荐

  1. java 核心技术卷一 知识点

    第九章 集合 1.Iterator和Iterable接口类,作用. 2.Collection接口类,作用. 3.Map接口类,作用.

  2. Window7 环境下 MariaDB 的安装 及使用

    MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可.开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将MySQL闭源的潜在风险,因此社区采用分支的方 ...

  3. HDU 1032 The 3n + 1 problem (这个题必须写博客)

    The 3n + 1 problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. HDU2825 Wireless Password —— AC自动机 + 状压DP

    题目链接:https://vjudge.net/problem/HDU-2825 Wireless Password Time Limit: 2000/1000 MS (Java/Others)    ...

  5. 分享知识-快乐自己:Hibernate框架常用API详解

    1):Configuration配置对象 Configuration用于加载配置文件. 1): 调用configure()方法,加载src下的hibernate.cfg.xml文件 Configura ...

  6. SpringMVC框架<mvc:default-servlet-handler/>的作用

    1.创建一个新工程 Eclipse下新建一个web项目,File>New>Dynamic Web Project     2.添加Jar包     3.配置Web.xml     4.配置 ...

  7. Java se 知识图解

  8. zepto.fullpage

    内容来自:颜海镜 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  9. BrowserSync(省时的浏览器同步测试工具)

    第一步:安装node 第二步:安装BrowserSync npm install -g browser-sync 第三部:启动BrowserSync 假如我在D盘建立一个文件test,里面分别包括in ...

  10. Spring笔记02(3种加载配置文件的方式)

    1.不使用Spring的实例: 01.Animal接口对应的代码: package cn.pb.dao; /** * 动物接口 */ public interface Animal { //吃饭 St ...