一.设计目的:熟悉Linux编程环境,加强对Linux命令的理解及函数的运用
二.设计内容:
在Linux环境下模拟实现简单命令解释器(即定义一个命令使它具有Linux中某些命令的功能)
例如:定义mydir使它具有dir 的功能
即在Linux环境中 $ mydir 和 $dir 作用一样
就实现了dir命令的解释。
(1)要求实现的基本命令包括:
定义 mypwd 具有 pwd //显示当前所在目录的路径名
定义 mylist 具有 list //列出指定目录名中的所有目录及文件
定义 mycd 具有 cd //改变当前工作目录
定义 mymkdir 具有 mkdir //新建目录
定义 myrmdir 具有 rmdir //删除目录
定义 myexit 具有 exit //退出命令解释程序
(2)可选做的扩展命令包括:
定义 myrename 具有 rename <旧文件名> <新文件名> //重命名一个文件或目录
定义mycopy 具有 copy <已存在的文件名> <副本文件名或路径> //复制一个已存在的文件
定义myfind 具有 find <目录> -name <待查找的文件名> //在指定的目录及其子目录中查找指定的文件(输入文件名),并输出查找到的文件的绝对路径。
#include<iostream> // 主要用于一些标准输入输出:cin,cout操作
#include<cstring> // 标准C++函数库,主要用于字符串处理
#include<sys/types.h> // 基本系统数据类型
#include<sys/stat.h> // 文件状态
#include<dirent.h> // 文件操作函数
#include<stdlib.h> // 常用的系统文件exit()用到
#include<stdio.h> // C语言标准输入输出
#include<fcntl.h> // 文件控制
#include<unistd.h> // 对于类 Unix 系统,unistd.h 中所定义的接口通常都是大量针对系统调用的封装
#include<sys/types.h> // Unix/Linux系统的基本系统数据类型的头文件,含有size_t,time_t,pid_t等类型
#include<sys/stat.h> // 文件状态
#include<time.h> // 定义关于时间的函数
#include<queue> // 主要包括循环队列queue和优先队列(也就是堆)
using namespace std;
// 方法声明
void mymkdir();
void mycd();
void mycopy();
void mypwd();
void mylist();
void myexit();
void myrmdir();
void myrename();
/**
* main()方法
* return 0
**/
int main(int argc, char *argv[])
{
cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<<endl;
cout<<"---该程序是为了模拟linux命令终端,并实现了简单的命令!---"<<endl;
cout<<"--- 您可以根据以下命令来模拟linux系统上对应的功能~ ---"<<endl;
cout<<"1、mypwd(显示当前所在目录的路径名)"<<endl;
cout<<"2、mylist(列出指定目录名中的所有目录及文件) "<<endl;
cout<<"3、mycd(改变当前工作目录)"<<endl;
cout<<"4、mymkdir(新建目录) "<<endl;
cout<<"5、myrmdir(删除目录)"<<endl;
cout<<"6、myexit(退出命令解释程序)"<<endl;
cout<<"7、myrename(重命名一个文件或目录)"<<endl;
cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<<endl;
string str;
// 如果输入的字符串不等于exit,即之后的命令都是在不等于exit的条件下进行
while(str != "exit") {
//shell 提示
cout<<"[linux_shell@]$";
cin>>str; //输入一个命令
if(str == "mypwd"){
// 如果命令是mypwd,那么执行mypwd()函数,功能是显示当前目录!
mypwd();
}
if(str == "mylist"){
// 如果命令是mylist,那么执行mylist()函数,功能是列出指定目录名中的所有目录及文件
mylist();
}
if(str == "mycd") {
// 如果命令是mycd,那么执行mycd()函数,功能是切换当前工作目录
mycd();
}
if(str == "mymkdir"){
// 如果命令是mymkdir,那么执行mymkdir()函数,功能是创建一个空目录
mymkdir();
}
if(str == "myrmdir"){
// 如果命令是myrmdir,那么执行myrmdir()函数,功能是删除一个目录
myrmdir();
}
if(str == "myexit"){
// 如果命令是myexit,那么执行myexit()函数,功能是退出
myexit();
}
if(str == "myrename"){
// 如果命令是myrename,那么执行myrename()函数,功能是重命名
myrename();
}
}
return 0;
}
/**
* fuction: 展示当前目录,功能类型于linux上的[pwd]
* return : void
**/
void mypwd()
{
char path[255]; // 创建一个最大长度为255的字符数组
getcwd(path,sizeof(path)); //调用getcwd()函数
cout<<"-当前目录为-"<<endl;
cout<<path<<endl; //打印出当时目录
}
/**
* fuction: 展示当前目录下的文件夹或文件
* return : void
*/
void mylist()
{
DIR * dir; // DIR数据类型表示目录流 (DIR* like FILE*)
struct dirent* ptr;
char dirname[50];
cout<<"请输入目录名(如: .代表当前目录, ..代表父目录)"<<endl;
cin>>dirname;
dir = opendir(dirname);
if(dir == NULL)
{
cout<<"没有权限打开该目录或没有该目录"<<endl;
} else
{
cout<<"["<<dirname<<"]"<<"目录的文件如下: "<<endl;
// readdir()函数循环遍历目录下的文件,并把指针指向下一个文件或目录
while((ptr = readdir(dir)) != NULL)
{ // 如果目录名不等于 . 或者 .. 的话(因为 . 和 .. 和每个目录都会有的, 如果只有这两个,可以说代表该目录为空)
if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0){}
// 否则就读出文件名
else
cout<<ptr->d_name<<"\n";
}
}
// 关闭文件流
closedir(dir);
cout<<endl;
}
/**
* function; 改变当前目录路径
* return: void
*/
void mycd()
{
char dirname[20];
cout<<"请输入要切换的目录名"<<endl;
cin>>dirname;
// 切换成就打印出当前路径
if(!chdir(dirname))
{
cout<<getcwd(dirname,sizeof(dirname))<<endl;
}
else
{
cout<<"要切换的目录不存在!"<<endl;
}
}
/*
function: 创建一个新目录,并赋予最高权限(0777, 可读可写可执行)
return: void
*/
void mymkdir()
{
char filename[20];
cout<<"请输入新创建的目录名"<<endl;
cin>>filename;
// 执行成功返回 0
if(!mkdir(filename,0777))
{
cout<<filename<<" 创建成功 "<<endl;
}
}
/*
function: 删除一个目录
return: void
*/
void myrmdir()
{
char filename[20];
cout<<"请输入目录名"<<endl;
cin >> filename;
// 执行成功返回 0
if(!rmdir(filename))
{
cout<<filename<<" 删除成功!"<<endl;
}
else
cout<<filename<<" 删除失败!"<<endl;
}
/*
function: 重命名
return: void
*/
void myrename()
{ char filename1[20],filename2[20];
cout<<"请依次输入原文件(目录)名、新文件名(目录)"<<endl;
cin>>filename1>>filename2;
// 创建成功返回 0
if(!rename(filename1,filename2))
{
cout<<filename1<<" 成功被重命名为 "<<filename2<<endl;
}
else
cout<<filename1<<" 重命名失败,请检查权限及是否有该文件(目录)"<<endl;
}
/*
function: 退出程序
return: 0
*/
void myexit()
{
exit(0);
}