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

一.程序概述

1.进入系统概述

本次课程设计是在红帽Linux发行版(Red Hat Enterprise Linux AS release 4 (Nahant Update 4)))环境下运行,内核为:Kernel 2.6.9-42.ELsmp on an i686。

以下为进入Linux操作系统命令行界面

cd os_design进入os_design这个目录

pwd显示当前路径为:/home/10131/os_design

这个路径为本次操作系统课程设计的目录

ls显示os_design下的文件:cmd.cpp为本次课程设计的源文件,采用语言为C++

执行命令g++ -o cmd cmd.cpp

产生可执行文件:cmd

在命令行键入:./cmd就可以直接运行

2.源程序完成的功能

本次课程设计在Linux环境下模拟实现命令解释器:本人实现的功能如下:

1.使用pwd命令,实现查看目录所处路径的功能。

2.使用dir命令,实现显示列出指定目录名中的所有目录及文件的功能。

3.使用cd命令,实现改变工作目录的功能。

4.使用newdir命令,实现创建新的目录的功能。

5.使用deldir命令,实现删除目录的功能。

6.使用rename命令,实现重命名一个文件或目录的功能。

7.使用find命令,实现查找指定目录下及其子目录的指定文件。

8.使用date命令,实现显示当前日期。

9.使用exit命令,实现退出命令行模式。

二.概念原理

本次操作系统课程设计使用的语言为C++,包含的头文件大多是Linux下c的函数库。通过调用相关的函数库来实现模拟shell命令操作。下面是对一些概念原理的说明:

1.源程序包含的头文件

#include//主要用于一些标准输入输出:cin,cout操作

#include//标准C++函数库,主要用于字符串处理

#include//基本系统数据类型

#include//文件状态

#include//文件操作函数

#include//文件控制

#include//定义关于时间的函数

#include//文件树漫游

以上是整个源程序涉及到的一些函数头文件

2.函数概念说明

以下是对程序调用Linux c函数库的方法说明:

调用getcwd()函数

函数原型:char * getcwd(char * buf,size_t size);

函数说明:getcwd()会将当前的工作目录绝对路径复制到参数buf所指的内存空间,参数size为buf的空间大小。在调用此函数时,buf所指的内存空间要足够大,若工作目录绝对路径的字符串长度超过参数size大小,则回值NULL,errno的值则为ERANGE。倘若参数buf为NULL,getcwd()会依参数size的大小自动配置内存(使用malloc()),如果参数size也为0,则getcwd()会依工作目录绝对路径的字符串程度来决定所配置的内存大小,进程可以在使用完此字符串后利用free()来释放此空间。

返回值:执行成功则将结果复制到参数buf所指的内存空间,或是返回自动配置的字符串指针。失败返回NULL,错误代码存于errno。

调用opendir()函数

函数原型:DIR * opendir(const char * name);

函数说明:opendir()用来打开参数name指定的目录,并返回DIR*形态的目录流,和open()类似,接下来对目录的读取和搜索都要使用此返回值。

返回值:成功则返回DIR*型态的目录流,打开失败则返回NULL。

调用readdir()函数

函数原型:struct dirent * readdir(DIR * dir);

函数说明:readdir()返回参数dir目录流的下个目录进入点。

结构dirent定义如下struct dirent

{

ino_t d_ino;

ff_t d_off;

signed short int d_reclen;

unsigned char d_type;

har d_name[256;

};

d_ino此目录进入点的inode

d_off目录文件开头至此目录进入点的位移d_reclen _name的长度,不包含NULL字符d_type d_name所指的文件类型d_name文件名

返回值:成功则返回下个目录进入点。有错误发生或读取到目录文件尾则返回NULL。

附加说明:EBADF参数dir为无效的目录流。

调用closedir()函数

函数原型:int closedir(DIR *dir);

函数说明:closedir()关闭参数dir所指的目录流。

返回值:关闭成功则返回0,失败返回-1,错误原因存于errno中。

调用chdir()函数

函数原型:int chdir(const char * path);

函数说明:chdir()用来将当前的工作目录改变成以参数path所指的目录。

返回值:执行成功返回0,失败返回-1;

调用mkdir()函数

函数原型:int mkdir(const char *pathname, mode_t mode);

函数说明:mkdir()函数以mode方式创建一个以参数pathname命名的目录,mode定义新创建目录的权限。

返回值:若目录创建成功,则返回0,否则返回-1;

调用rmdir()函数

函数原型:int _rmdir(const char *dirname);

函数说明:rmdir()函数删除以参数dirname为命名的目录。

返回值:若目录删除成功,则返回0,否则返回-1;

调用rename()函数

函数原型:int rename(const char * oldpath,const char * newpath);

函数说明:rename()会将参数oldpath所指定的文件名称改为参数newpath所指的文件名称。若newpath所指定的文件已存在,则会被删除。

返回值:执行成功则返回0,失败返回-1。

调用ftw()函数

表头文件:#include 函数原型:int ftw(const char *dir, int (*fn) (const *file, const struct stat *sb, int flag), int depth)函数说明:ftw()会从参数dir指定的 开始,往下一层层地递归式遍历子 。ftw()会传三个参数给fn(),第一个参数*file指向当时所在的 路径,第二个参数是*sb,为stat结构指针,第三个参数为旗标,有下面几种可能值:

FTW_F一般文件FTW_D 目录

FTW_DNR不可读取的 ,此 以下将不被遍历FTW_SL符号连接FTW_NS无法取得stat结构数据,有可能是 问题最后一个参数depth代表ftw()在进行遍历 时同时打开的文件数。ftw()在遍历时每一层 至少需要一个文件描述词,如果遍历时用完了depth所给予的限制数目,整个遍历将因不断地关文件和开文件操作而显得缓慢.如果要结束ftw()的遍历,fn()只需返回一非零值即可,此值同时也会是ftw()的返回值。否则ftw()会试着走完所有的 ,然后返回0.返回值:遍历中断则返回fn()函数的返回值,全部遍历则返回0,若有错误发生则返回-1

三.完成情况

完成了整个操作系统课程设计的命令行功能基本要求:

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

dir //列出指定目录名中的所有目录及文件

cd//改变当前工作目录

newdir//新建目录

deldir//删除目录

exit//退出命令解释程序

其中直接输入dir不能直接显示文件和目录,需要在使用dir .,才能显示当前文件夹下的目录和文件

基本完成了以下几个扩展命令的动能要求:

rename //重命名一个文件或目录

find -name //在指定的目录及其子目录中查找指定的文件

date//显示当前日期

其中find命令,只能查询指定目录的文件,不能指定待查找的文件名。

通过测试,以上所有命令都运行正常。整个程序,代码实现简单清晰,没有太复杂的算法。基本上就是对函数的调用实现。运行结果又较好的提示信息,无论是成功错误都提示相应的信息。源代码的注释内容也非常清晰,方便查看理解函数调用的功能。

四.详细设计

下面是对整个程序功能实现的介绍:

1.pwd()函数

主要调用了getcwd()函数,获取当前工作目录的绝对路径。

相关代码:

char ptr[80];

getcwd(ptr, sizeof(ptr));

getcwd函数会将当前的工作目录绝对路径复制到参数buf所指的内存空间,

所以直接输出ptr就可以得到当前目录的绝对路径。

2.dir()函数

dir()函数主要实现显示指定目录下的目录和文件

调用了opendir()、readdir()、closedir()等对文件权限操作的函数

下面是主要代码,输出目录

dir = opendir(dirname);

while((ptr = readdir(dir)) != NULL)

{

// if the d_name is equal with "." or ".." ,do nothing

if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0){}

// if not , print the ptr->d_name

else

cout<d_name<

// count the d_name

count++;

// if count % 8 == 0, line feed

if(count % 8 == 0)

cout<

}

closedir(dir);

详细设计说明:

1.通过目录名dirname,调用opendir()函数打开目录流

2.调用readdir()函数读取目录,返回dirent*数据结构

3.将d_name(目录名/文件名)输出

4.有开的过程,就应该有关的过程,调用closedir()函数关闭目录流。

3.cd()函数

cd函数主要实现切换目录的功能。详细设计如下:

调用chdir()函数切换目录,如果切换成功就返回0,切换失败返回-1;

4.newdir()函数

newdir函数主要实现,新建目录的功能。详细设计如下:

调用mkdir()函数就可以创建新的目录,如果创建成功返回0,创建失败返回-1;

实现代码如下:

if(mkdir(filename,0777) == 0)

{

cout<

}

else

{cout<

}

其中0777设置文件为最大权限

5.deldir()函数

deldir函数主要实现了删除目录的功能。详细设计如下:

调用rmdir()函数就可以将指定目录删除,如果创建成功返回0,创建失败返回-1;

实现代码跟第4点类似。这里就不多说了。

6.rename()函数

rename函数主要实现了对文件进行重命名的功能。详细设计如下:

调用rename(filename1, filename2);就可以将filename1更改为filename2,如果更改成功的话,返回0,否则返回-1;

7.find()函数

find函数主要实现了查找指定目录的文件,并列出每一个文件的类型,这里指列出来了目录和文件类型。

find函数调用了ftw库函数,

8.date()函数

date函数实现的功能是显示当前日期。详细设计说明:

代码实现如下:主要是调用ctime()函数返回一个关于日期的字符串。直接将这个字符串输出,就可以知道当前日期和时间。

五.使用情况

./cmd运行程序

会显示以上9条命令使用提示,并指令提示符为[姓名@]$

1.使用pwd命令----显示当前目录的绝对路径

2.使用dir命令显示指定目录的文件和目录

3.使用cd命令更换目录

4.使用newdir命令新建目录

5.使用deldir命令删除目录

6.使用rename命令重命名目录

7.使用find命令查找指定目录的文件

8.使用date命令显示当前日期和时间

9.使用exit命令退出命令行

六.设计总结

1.遇到的困难及解决的问题

一段时间没有使用C++/C语言,有些函数的使用不怎么清晰,用惯了java的思考模式和API,转换过来用C++语言来编程,感觉有点不怎么舒服。后来,简单复习了C++的输入输出还有头文件包含等知识,还是把以前的底子给捡起来了。整个课程设计,遇到的问题并不多,难度是如果去理解Linux c函数库的调用。需要花时间去理解每一个函数的作用和相关参数的作用。刚开始做的时候,也是不知道怎么开始,之前把问题想得复杂化了,后来通过一步一步实现每个指令,才慢慢找到解决的办法。

2.总结与感想

总的来说,整个课程设计还算比较顺利,因为对Linux操作系统接触得并不多,对一些命令行的实现还不怎么清楚,后来通过查阅资料,自己用虚拟机运行了Linux Ubuntu发行版来研究了一下。发现Linux确实非常简洁好用,我非常喜欢这样的系统。历时两天的时间,把程序设计出来了,也认真写了下这次的文档。感觉通过一段时间的学习,自己的编程能力确实变强了,但还是有许多不足。在程序设计过程中,要学会查看文档,因为很多文档都是英文,这就需要英文好一点。我也在克服查看英文文档的障碍,努力提升自己的英文阅读能力。通过这次课程设计,也让自己捡起了C++这门语言,熟悉了Linux环境下的一些命令操作,并且让我有了极大兴趣去研究Linux,我在接下来的时间里也会使用和学习Linux程序设计。总的来说,感觉不错。

七.参考文献

《Linux程序设计第4版》,《The GUN C Library Manual》

源程序代码如下:

因为解决乱码问题,所以小巫把注释都改为了英文,我的英文有点粗,希望有人能看懂。

/**source file: cmd.cpp

@stunum: 201038889071

@classnum: 31

@author:wwj

@date:2012/12/16

@decription:Linux Operation System

**/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

usingnamespacestd;

//declare method

voidpwd();//show current absolute path

voiddir();//show directory and file

voidcd();//change directory

voidnewdir();//make new directory

voiddeldir();//delete directory

voidrename();//rename the directory's name

voidfind();//find the assign file in the assign directory

voiddate();//show the date of now

intfn(constchar*file,conststructstat *sb,intflag);

/**

* main method

* return 0

**/

intmain(intargc,char*argv[])

{

cout<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<

cout<>>>>>Welcome to wwj's cmd line<<<<<

cout<

cout<

cout<"<

cout< "<

cout< "<

cout< "<

cout<  "<

cout<"<

cout<

cout<

cout<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<

string str;

//when the str is  equal with the string "exit",break the cycling

while(str !="exit") {

//shell prompt

cout<

cin>>str;//enter the command

if(str =="pwd"){

// if str is equal with the string "pwd", execute the pwd() method

pwd();

}

if(str =="dir") {

// if str is equal with the string "dir", execute the dir() method;

dir();

}

if(str =="cd") {

// if str is equal with the string "dir", execute the cd() method;

cd();

}

if(str =="newdir"){

// if str is equal with the string "newdir", execute the newdir() meth

newdir();

}

if(str =="deldir"){

// if str is equal with the string "deldir", execute the deldir() mte

deldir();

}

if(str =="rename") {

// if str is equal with the string "rename", execute the rename() meth

rename();

}

if(str =="date") {

// if str is equal with the string "date", execute the date() method;

date();

}

if(str =="find") {

// if str is equal with the string "find",execute the find() method

find();

}

}

return0;

}

/**

* fuction:show current directory path

* return : void

**/

voidpwd()

{

charptr[80];// create a character array with the size of 80

getcwd(ptr,sizeof(ptr));//invoke the getcwd() method

cout<

}

/**

* fuction: show current directory's directory or file

* return : void

*/

voiddir()

{

DIR * dir;//The DIR data type represents a directory stream

structdirent* ptr;

intcount = 0;

char*dirname;

cin>>dirname;

dir = opendir(dirname);

if(dir == NULL)

{

cout<

}

//The opendir function opens and returns a directory stream for reading the

rectory whose file name is dirname

//This readdir function reads the next entry from the directory.

while((ptr = readdir(dir)) != NULL)

{// if the d_name is equal with "." or ".." ,do nothing

if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0){}

// if not , print the ptr->d_name

else

cout<d_name<

// count the d_name

count++;

// if count % 8 == 0, line feed

if(count % 8 == 0)

cout<

}

// close directory stream.

closedir(dir);

cout<

}

/**

* function; change the directory path

* return: void

*/

voidcd()

{

chardirname[20];

cin>>dirname;

//if change the directory successful

if(chdir(dirname) == -1)

{

cout<

}

else

{

cout<

}

}

/**

* function : make a new directory

* return: void

*/

voidnewdir()

{

charfilename[20];

cin >> filename;

//S_IFDIR is the mode, the meaning is the file'type is a dirtectory

if(mkdir(filename, 0777) == 0)

{

cout<

}

else

{  cout<

}

}

/**

* function : delete a directory

* return: void

*/

voiddeldir()

{

charfilename[20];

cin >> filename;

// if delete the dirtectory successful return 0

if(rmdir(filename) == 0)

{

cout<

}

else

cout<

}

/**

* function: rename the diretory'name

* return :void

*/

voidrename()

{

charfilename1[20], filename2[20];

cin>>filename1>>filename2;

// if the directory rename successful it will return 0

if(rename(filename1, filename2) == 0)

{

cout<

}

else

cout<

}

/**

* function: find the assign directory and child directory's assign file

* return: void

*/

voidfind()

{

chardirname[50];

cin>>dirname;

// ftw(const char *dir, int(*fn)(const *file, const struct stat *sb,int fl

,intdepth)

ftw(dirname, fn,500);

}

/**

* function: ergodic every layer directory and print the files

* @param *file

* @param struct stat *sb

* @param flag

* return int

*/

intfn(constchar*file,conststructstat *sb,intflag)

{

if(flag == FTW_D)

cout <

elseif(flag == FTW_F)

cout <

return0;

}

/**

* function: show the current date

* return : void

*/

voiddate()

{

time_ttimeval;

(void)time(&timeval);

string timestr;

// invoke the ctime fuction and return the string

timestr = ctime(&timeval);

cout<

}

linux简单命令解释器设计,Linux环境下模拟实现命令解释器相关推荐

  1. 操作系统课程设计--在Linux环境下模拟实现简单命令解释器(C++代码)

    操作系统课程设计要求 一.设计目的 熟悉Linux编程环境,加强对Linux命令的理解及函数的运用 二.设计内容 1. 在Linux环境下模拟实现简单命令解释器. (1)要求实现的基本命令包括: pw ...

  2. linux环境下使用sort命令完成常见排序操作

    文章目录 前言 命令作用 常见选项 数据文件 核心参数 用法展示 按照指定列排序 将排序结果存入指定文件 查看文件是否已经排序好 去掉排序结果中的重复行 按照数值结果进行排序 反向排序 自定义分割字符 ...

  3. linux curl命令 post,linux环境下使用curl命令设置Header参数发送post请求

    linux环境下使用curl命令设置Header参数发送post请求 linux环境下使用curl命令设置Header参数发送post请求 案例1:curl命令发送post请求并且获取返回结果以及响应 ...

  4. Linux系统编程及应用——ubuntu环境下

    Linux系统编程及应用--ubuntu环境下 程序由业务逻辑和系统访问两部分构成的.其中,业务逻辑是根据业务需求,按照设计好的逻辑规则,处理信息,与系统(平台)无关的:而系统访问则是利用操作系统所提 ...

  5. conda添加清华镜像源在cmd环境下执行下列命令

    为conda添加清华镜像源在cmd环境下执行下列命令 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda ...

  6. kali没有arpspoof命令_windows环境下使用python3命令

    最近kali崩溃了,于是就使用了一段时间的win 10,对于一些两种系统之间的差异也是进行了一定的协同修复. 在kali下使用python命令就是调用的python2,使用python3命令就是调用的 ...

  7. 在linux环境下模拟实现简单命令解释器_git bash 竟然不支持 tree 命令

    别人家的孩子 以下故事,纯属虚构,如有雷同,绝不可能! git 是一个思维敏捷做事可靠的好管家,什么事交给他都很放心,文件再也不用担心丢失了,还得记住文件内容的更改变化. 可惜的是,git 是别人家的 ...

  8. Linux/Unix环境下的make命令详解

    无论是在linux还是在Unix环境中,make都是一个非常重要的编译命令.不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或make install.利用make工具,我们可以将大型 ...

  9. 基于linux的软plc设计,Linux环境下软PLC开发系统的设计与实现

    文章主要介绍了在Linux操作系统环境下,软PLC梯形图的编辑技术.采用基于面向对象的方法,在分析了梯形图组成元素的基础上,阐述了设计过程中使用的类层次结构,并根据梯形图动态存储的特点,描述了存储梯形 ...

最新文章

  1. java $.getjson_JQuery 获取json数据$.getJSON方法的实例代码
  2. python自动点赞_用Python模拟技巧带你实现自动抽屉登录自动点赞
  3. 求解第K个斐波那契质数
  4. APK Expansion Files / Obb 接入介绍
  5. 工具推荐|程序员必须知道的11款新型编程工具
  6. 4.8 计算机网络之网络层设备路由器
  7. github上面图片不显示
  8. hdfs 备份数配置_大数据||HDFS HA配置详解
  9. MySQL使用Navicat导出Excel时数字展示会变成科学计数法
  10. Teamview使用方法说明
  11. 华为系列服务器账号密码,常用设备管理口默认用户名密码汇总
  12. Discuznbsp;x2.5单页制作的教程
  13. 浪潮发布PS Cloud 开源+云ERP会给中小企业带来哪些红利?
  14. Dynamics CRM 中 Xrm.Page.getControl('name').getValue() 和 Xrm.Page.getAttribute('name').getValue() 的区别
  15. SUMO无法创建xml文件 Could not build output file
  16. matlab获取晶粒边界,晶粒边界
  17. 区块链仿真工具SimBlock
  18. 项目管理-PMP-第7章 项目质量管理
  19. http://www.huxiu.com/ 很多互联网观点
  20. Cnic.LinkHelper

热门文章

  1. Docker中修改MySQL的密码
  2. Axure 文本框输入字数限制
  3. 我现在想去深圳找份普通的工作,深圳那边现在工作好找吗?
  4. linux设置文件句柄数
  5. 善用Navicat的SSH代理
  6. sql排序(想让字段为空的值放到最后)
  7. CCF考试笔记(c++)
  8. 如何在 Ubuntu 20.04 上安装 GCC(build-essential)
  9. 什么是io流,以及程序文件的处理
  10. Spring框架 -- 开篇搭建脚手架