操作系统大作业:在Linux环境下模拟实现简单命令解释器(代码部分)

好家伙

1. 题目要求

一、 课程设计(大作业)目的

熟悉Linux编程环境,加强对Linux命令的理解及函数的运用,完成一个操作系统的部分系统的设计过程、编码、调试,锻炼实际应用能力。

二、 课程设计(大作业)具体要求

2.1 课程设计题目

在Linux环境下模拟实现简单命令解释器。

(1)要求实现的基本命令包括:

pwd //显示当前所在目录的路径名

list <目录名> //列出指定目录名中的所有目录及文件

modifydir <目录名或路径> //改变当前工作目录

makedir <目录名> //新建目录

deldir <目录名> //删除目录

exit //退出命令解释程序

(2)可选做的扩展命令包括:

rename <旧文件名> <新文件名> //重命名一个文件或目录

copy <已存在的文件名> <副本文件名或路径> //复制一个已存在的文件

find <目录> -name <待查找的文件名> //在指定的目录及其子目录中查找指定的文件,并输出查找到的文件的绝对路径。

(3)提示:整个程序的大致框架可参考如下:

while ( exit未被输入 )

{ 接收键盘的一行输入

分析输入的命令

对输入的命令进行处理,调用系统函数实现功能

}

2.2 设计要求

(1) 设计必须在Linux环境下进行。

(2) 命令解释程序的提示符为:姓名拼音@

(3) 程序编写中不得使用system()系统调用。

(4) 整个程序必须严格经过测试,完成所有基本功能。源程序应有较详尽的注释。

2.3可能用到的系统函数:

open(),close(),read(),write(),creat()

chdir(), opendir(),readdir(),rewinddir(),closedir(),rmdir(),mkdir()

getcwd(), ftw()

2.思路以及代码

看上去非常难,实际上只需要把关键函数再封装一遍就好了

复制代码
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<dirent.h>
#include<fcntl.h>
#include<time.h>

using namespace std;

int C_fd;           //文件描述符
char filename[100]; //文件名
int isopen = 0;     //打开状态
char *pargv[5] = {"ls", "-l", NULL, NULL};
char findFileName[50]={""};         //用于存放要查找的文件名 
int fileFlag = 0;                   //用于标记是否找到查找的文件名
int num=0;
string file;

//显示当前所在目录的路径名  mypwd 
void mypwd() {
    char path[100];
    getcwd(path,100);
    cout<<"当前目录: "<<path<<endl;
}

//列举指定目录中的所有目录及文件    mylist 
//用函数opendir()打开目录,并且用readdir()函数读取每一个目录节点,打印输出信息,最后用函数closer()关闭 
bool mylist(string dir) {
    DIR* d = opendir(dir.c_str());
    if(d==NULL) {
        return false;
    } else {
    struct dirent *dirent;
        while(dirent=readdir(d)) {
        cout<<endl;
        cout<<"  "<<dirent->d_name<<"  "<<dirent->d_type<<"  "<<dirent->d_reclen<<endl;
        cout<<endl;
    }
    closedir(d);
        return true;
    }
}

//显示当前日期-mydate 
void date()
{
  time_t timeval;
  (void)time(&timeval);
  string timestr;
  // invoke the ctime fuction and return the string
  timestr = ctime(&timeval);
  cout<<"当前时间: "<<timestr<<endl;
}

// 改变当前目录-mycd 
bool mycd(string path) {
    if(chdir(path.c_str())==0) {
        return true;
    } else {
        return false;
    }
}

//新建目录-mymkdir
bool mymkdir(string dir) {
    if(mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)==0) {
        return true;
    } else {
        return false;
    }
}

//删除目录-myrmdir
bool myrmdir(string dir) {
    if(rmdir(dir.c_str())==0) {
        return true;
    } else {
        return false;
    }
}

//重命名文件或目录-myrename
bool myrename(string lastname,string newname) {
    if(rename(lastname.c_str(),newname.c_str())==0) {
        return true;
    } else {
        return false;
    }
}

//复制文件-mycopy 
//先判断文件是否存在,存在则在原来要复制的文件名后加(1),否则直接复制 
bool mycopy(string existname,string newname) {
    int fo1,fo2;
    char buf[1024];
    fo1=open(existname.c_str(),O_RDONLY);
    if(fo1==-1) {    
    return false;
    } else {
    fo2=open(newname.c_str(),O_RDONLY);
    if(fo2!=-1) {
        int i;
        cout<<"确定替换文件?"<<endl;
        cout<<"输入1为确定,非1为否定.";
        cin>>i;
        if(i!=1) {
        newname+="(1)";
        }
        close(fo2);
    }
    fo2=open(newname.c_str(),O_WRONLY|O_CREAT,S_IRWXU);
    int size = read(fo1,buf,sizeof(buf));
    write(fo2,buf,size);
    close(fo1);
    close(fo2);
    return true;
    }
}

//创建文件功能-- mycreat(open打开文件)
void creatopen()
{
    cout<<"请输入要打开/创建的文件名: "<<endl;
    cin>>filename;
    C_fd = open(filename, O_RDWR|O_TRUNC, 0666);
    if (C_fd >= 0)
    
    {
        isopen = 1, cout<<"该文件已存在,打开成功"<<endl;
        pargv[2] = (char *)malloc(50);
        strcpy(pargv[2], filename);
    }
    else
    {
        C_fd = open(filename, O_CREAT|O_RDWR|O_TRUNC,0666);
        if (C_fd >= 0)
            isopen = 1, cout<<"该文件不存在,新建成功:"<<endl;
        else
            isopen = 0, cout<<"打开/新建失败"<<endl;
    }
}
//创建文件功能-- mycreat(write写入文件内容)
void creatwrite()
{
    char buffer[1024];

    cout<<"请输入文件内容(按回车保存):"<<endl;
    cin>>buffer;

    int t = write(C_fd, buffer, strlen(buffer));
    if (t == -1)
        cout<<"保存失败!"<<endl;
    else
        cout<<"保存成功!"<<endl;
    cout<<"该文件内容为:";
    cout<<buffer<<endl;
}

//删除文件-mydelete
bool mydelete(string dir) {
    if(unlink(dir.c_str())==0) {
        return true;
    } else {
        return false;
    }
}

//菜单
void menu() {
    system("clear");
    cout<<"*********************************************"<<endl;
    cout<<"* 基本命令"<<endl;
    cout<<"* 1.tanghan@pwd:显示当前所在目录的路径名"<<endl;
    cout<<"* 2.tanghan@list <目录名>:列出指定目录名中的所有目录及文件"<<endl;
    cout<<"* 3.tanghan@modifydir <目录名或路径>:改变当前工作目录"<<endl;
    cout<<"* 4.tanghan@makedir<目录名>:新建目录"<<endl;
    cout<<"* 5.tanghan@deldir<目录名> :删除目录"<<endl;
    cout<<"* 6.tanghan@exit:退出程序"<<endl;

    cout<<"* 拓展命令"<<endl;
    cout<<"* 7.tanghan@rename <旧文件名> <新文件名>:重命名一个文件或目录"<<endl;
    cout<<"* 8.tanghan@copy <已存在的文件名> <副本文件名或路径>:复制一个已存在的文件"<<endl;
    cout<<"* 9.tanghan@date:显示当前日期"<<endl;

    cout<<"*********************************************"<<endl;
    cout<<endl;
}

int main() {
    menu();
    string s;
    while(1) {
    cout<<"请输入你的指令:";
        cin>>s;
    //显示当前所在目录的路径名
        if(s=="tanghan@pwd"){
        menu();
        mypwd(); 
        } 
    //列出指定目录名中的所有目录及文件
    else if(s=="tanghan@list") {
        menu();
            cout<<"请输入指定一个目录:";
            string dir;
            cin>>dir;
            if(!mylist(dir)) {
             cout<<"目录打开失败或不存在!"<<endl;
            }
        } 
    //改变当前工作目录
    else if(s=="tanghan@modifydir") {
        menu();
        cout<<"请输入指定一个目录:";
        string path;
        cin>>path;
        if(!mycd(path)) {
             cout<<"目录打开失败或不存在!"<<endl;
            } else {
        cout<<"当前工作目录为 "<<path<<endl;
        }
        } 
    //新建目录
    else if(s=="tanghan@makedir") {
        menu();
        cout<<"请输入一个新的目录名:";
        string dir;
        cin>>dir;
        if(!mymkdir(dir)) {
             cout<<"创建目录失败!"<<endl;
            } else {
        cout<<"创建目录成功!"<<endl;
           }
        } 
    //删除目录
    else if(s=="tanghan@deldir") {
        menu();
        cout<<"请输入一个存在的目录名:";
        string dir;
        cin>>dir;
        if(!myrmdir(dir)) {
             cout<<"目录不存在或删除失败!"<<endl;
            } else {
        cout<<"成功删除目录!"<<endl;
        }
        } 
    //退出程序    
    else if(s=="tanghan@exit") {
        menu();
        cout<<"再见!"<<endl;
        return 0;
        } 
    //重命名一个文件或目录
    else if(s=="tanghan@rename") {
        menu();
        string lastname,newname;
        cout<<"请输入需要修改的目录名或文件名:";
        cin>>lastname;
        cout<<"请输入新的目录名或文件名:";
        cin>>newname;
        if(!myrename(lastname,newname)) {
        cout<<"重命名失败!"<<endl;
            } else {
            cout<<"重命名成功!"<<endl;
        }
        }
    //显示当前日期
    else if(s=="tanghan@date") {
        menu();
        date();
        }
    //创建/打开文件并写入
    else if(s=="tanghan@creat") {
        menu();
        creatopen();
        creatwrite();
    }
    //删除文件
    else if(s=="tanghan@delete") {
        menu();
        cout<<"请输入一个存在的文件名:";
        string dir;
        cin>>dir;
        if(!mydelete(dir)) {
             cout<<"文件不存在或删除失败!"<<endl;
            } else {
        cout<<"成功删除文件!"<<endl;
        }
        }
    //复制文件
    else if(s=="tanghan@copy") {
        menu();
        string existname,newname;
        cout<<"请输入需要复制的目录名或文件名:";
        cin>>existname;
        cout<<"请输入被复制的目录名或文件名:";
        cin>>newname;
        if(!mycopy(existname,newname)) {
        cout<<"复制失败!"<<endl;
            } else {
            cout<<"复制成功!"<<endl;
        }
        }
    //输入有误,重新输入
    else { 
        menu();
        cout<<"输入命令格式错误,请重新输入!"<<endl;
    }
    }
    return 0;
}