操作系统小组作业,实现一个简易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

最新文章

  1. axis2+struts拦截地址冲突问题
  2. Linux 命令行快捷键
  3. Eclipse调试常用技巧(转)
  4. C#_GDI+详细教程(图形图像编程基础)
  5. linux主机间复制文件
  6. POJ - 2041Unreliable Message
  7. ICP(迭代最近点)算法
  8. oracle日志总结
  9. 串操作,C++实现
  10. Swift - 42 - 类的基本使用
  11. mysql Fatal error encountered during command execution
  12. 使用visualvm 远程监控 JVM
  13. ActiveMQ + NodeJS + Stomp 极简入门
  14. oracle数据库-错误编码大全
  15. PAT1051:Pop Sequence
  16. 补充一下 sizeof
  17. vss登录invalid handle问题的解决办法
  18. 通过C/C++基于http下载文件
  19. anaconda使用以及创建python3.7+pytorch1.0虚拟环境以及Jupyter notebook初级使用
  20. Learning Git by Animations

热门文章

  1. Dijkstra的堆优化
  2. LeetCode:访问所有节点的最短路径【847】
  3. PAT 甲级 1065. A+B and C (64bit) (20) 【大数加法】
  4. 使用CL命令编译cpp文件
  5. smokeping 出现的问题
  6. 游戏引擎基于Handle的资源管理
  7. BZOJ 1614 [Usaco2007 Jan]Telephone Lines架设电话线:spfa + 二分【路径中最大边长最小】
  8. 安装与设置hexo
  9. 使用zlib实现gzip格式数据的压缩和解压
  10. sass与compass实战(读书笔记)