实验课题1Linux命令解释程序设计与实现.docx

上传人:b****1 文档编号:22997611 上传时间:2023-04-29 格式:DOCX 页数:23 大小:58.11KB
下载 相关 举报
实验课题1Linux命令解释程序设计与实现.docx_第1页
第1页 / 共23页
实验课题1Linux命令解释程序设计与实现.docx_第2页
第2页 / 共23页
实验课题1Linux命令解释程序设计与实现.docx_第3页
第3页 / 共23页
实验课题1Linux命令解释程序设计与实现.docx_第4页
第4页 / 共23页
实验课题1Linux命令解释程序设计与实现.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

实验课题1Linux命令解释程序设计与实现.docx

《实验课题1Linux命令解释程序设计与实现.docx》由会员分享,可在线阅读,更多相关《实验课题1Linux命令解释程序设计与实现.docx(23页珍藏版)》请在冰豆网上搜索。

实验课题1Linux命令解释程序设计与实现.docx

实验课题1Linux命令解释程序设计与实现

实验课题1:

Linux命令解释程序设计与实现

实验报告

1实验内容及要求

Linux命令解释程序功能设计要求:

1)选取和设计实现一组内部命令(五条以上);

2)外部命令执行采用直接调用exec系统调用的方式来实现;

3)至少一条内部命令采用直接调用相应系统调用的方式来实现;

4)系统环境变量(至少包括当前目录)支持;

5)在Linux操作系统上启用(或替换原命令解释程序Shell)测试验证。

2开发、运行及测试环境

1)虚拟环境软件:

OracleVMVirtualBox

2)操作系统:

OracleLinux6.5

3)编辑器:

vim

4)编译器:

gcc

3实验步骤

采用c语言编写该Linux命令解释程序。

首先包含unistd.h、sys/syscall.h等头文件以及完成各个功能的函数声明。

主程序中利用循环结构完成不限次的命令提示符显示和命令输入,并判别输入的命令是否合法,是内部命令还是外部命令。

将Linux命令解释程序的各个功能封装成函数,完成具体的命令执行处理。

实现具体功能步骤如下。

3.1采用间接调用实现的内部命令

3.1.1显示指定目录下文件列表

设计该命令关键词为“ls”,功能为用户输入该命令后,指定具体的目录路径,可显示在该目录下的文件列表,并将文件编号显示,格式为“file编号文件名”,每行显示一个文件的文件名。

如该过程中出现错误导致不能显示文件列表则输出具体错误提示。

采用间接调用相应系统调用的方式将该功能完成后封装为voidlist_()函数。

3.1.2显示当前路径

设计该命令关键词为“pwd”,功能为用户输入该命令后,在下一行显示当前路径并回车换行。

采用间接调用相应系统调用的方式将该功能完成后封装为voidpwd_()函数。

设计该命令关键词为“rename”,功能为用户输入该命令后,在下一行显示“pleaceinputtheoldfilename:

”,用户需输入需要重命名的文件名,然

后显示“pleaceinputthenewfilename:

”,用户需输入该文件的新的文件

名,即可完成对文件的重命名。

完成后显示提示重命名工作失败或成功。

采用间接调用相应系统调用的方式将该功能完成后封装为voidrename_()函数。

3.1.4显示输入内容

设计该命令关键词为“echo”,功能为用户输入该命令后,输入空格,然后输入需要显示的内容,即可在下一行显示上述用户希望输出的内容并回车换行。

采用间接调用相应系统调用的方式将该功能完成后封装为voidecho_()函数。

3.1.5使用帮助

设计该命令关键词为“help”,功能为用户输入该命令后,然后显示本命令解释程序的合法命令及其具体的功能说明。

采用间接调用相应系统调用的方式将该功能完成后封装为voidhelp_()函数。

3.1.6退出程序

设计该命令关键词为“exit”或“quit”,功能为用户输入该命令后,显示“thankyouforusing!

bye~”,之后该命令解释程序(Shell)退出到Linux

操作系统上的原命令解释程序Shell。

采用间接调用相应系统调用的方式完成。

因该功能代码较简单直接在主程序中实现并未封装为函数。

3.1.7设置和初始化系统环境变量

此处略,详见下文3.4系统环境变量支持中的说明。

3.2采用直接调用的内部命令

3.2.1文件拷贝

设计该命令关键词为“copy”,功能为用户输入该命令后,然后显示“pleaceinputthefilenametobecopied:

”,用户输入需要复制的文件的

文件名,然后显示“pleaceinputthenewfilename:

”,用户输入新拷贝文

件的文件名,即可完成文件的拷贝。

如该过程中出现错误导致文件拷贝不成功则输出具体错误提示。

采用直接调用系统调用的方式将该功能完成后封装为voidcopy_()函数。

3.3外部命令

3.3.1显示环境变量

设计该命令关键词为“env”,功能为用户输入该命令后,然后显示出所有的系统环境变量,每行显示一个。

采用直接调用exec系统调用的方式将该功能完成后封装为intenviron_()函数。

设计该命令关键词为“jobs”,功能为用户输入该命令后,然后显示出当前一系列进程和子进程。

采用直接调用exec系统调用的方式将该功能完成后封装为intjobs_()函数。

3.4系统环境变量支持

设计该命令关键词为“export”,功能为用户输入该命令后,输入需要设置的系统变量名称和变量值,格式为“[系统变量名称]=[系统变量值]”然后即可设置完成。

采用间接调用相应系统调用的方式分别实现保存在本地用户变量中和保存在系统环境变量种,并分别封装为voidenv_store()和voidenv_export()函数。

最后将上述功能函数完成后封装为voidexport_()函数。

以上代码编写完成后,通过Linux操作系统中的gcc编译器编译后运行,验证是否运行成功,功能是否完善,是否存在错误或问题。

返回上述步骤修改代码,直到测试验证通过。

4关键数据结构和算法流程在主程序中的关键数据结构是字符数组,用于接收用户输入的命令。

关键的算法结构是循环结构,利用死循环结构用户可以不限次输入命令供程序执行处理,直到用户输入退出的命令则退出该循环结构,程序退出。

在循环结构中,输出系统命令提示符,提示用户输入。

用户输入命令存入字符串数组后,将该命令与预设的命令依次比较是否符合某一个,则进入相应命令的处理过程。

若均不符合则输出输入错误的提示,继续回到循环开头输出系统命令提示符等待下一次输入命令。

4.1采用间接调用实现的内部命令

4.1.1显示指定目录下文件列表关键数据结构是另一字符数组,用于接收用户在命令后输入的指定目录;结构体“structdirent*entry”,用于存储该目录下文件,包括文件名;变量DIR*olist用于存储打开目录函数的返回值,判别是否打开成功并读取该目录下文件。

该命令是间接调用相应的系统调用实现的方式。

关键算法是用户输入该命令和指定路径后,调用opendir()函数打开指定的目录。

若返回值为空则打开失败,输出错误提示。

利用循环结构调用readdir()函数读取该目录下文件,并依次输出文件序号和文件名。

循环结束后,调用closedir()函数关闭该目录。

若关闭失败则输出错误提示。

4.1.2显示当前路径关键数据结构为字符型指针,用于指向当前路径。

该命令是间接调用相应的系统调用实现的方式。

关键算法是用户输入该命

令后,调用getcwd()函数获取当前路径,由指针指向该空间,然后输出该路径。

最后释放该指针空间。

关键数据结构为两个字符型数组,用于存储新文件名和旧文件名。

该命令是间接调用相应的系统调用实现的方式。

关键算法是用户输入该命令后,分别输入旧文件名和新文件名存入数组。

调用rename()函数,将文件重命名。

最后输出命名成功或失败的提示。

4.1.4显示输入内容

关键数据结构为字符型数组,用于存储用户除命令外输入的内容。

该命令无需调用系统调用。

关键算法是用户输入该命令后,将命令后的内容除空格外依次输出,最后输出换行即可。

4.1.5使用帮助

在该函数中输出定义好的命令和相应使用帮助即可。

4.1.6退出程序

输出用户提示,调用函数exit()退出程序即可。

4.1.7设置和初始化系统环境变量

此处略,详见下文4.4系统环境变量支持中的说明。

4.2采用直接调用的内部命令

4.2.1文件拷贝

关键数据结构为三个字符型数组,用于存储需拷贝的文件的文件名和拷贝文件的文件名以及拷贝的部分文件内容。

该命令是直接调用相应的系统调用实现的方式。

关键算法是用户输入该命令以及需拷贝的文件的文件名和拷贝文件的文件名后,使用syscall()函数和系统调用号SYS_open,采用只读模式打开需要拷贝的文件,若打开失败输出相应提示。

使用syscall()函数和系统调用号SYS_read,读取该文件的内容和字节数量,若读取失败输出相应提示。

使用syscall()函数和系统调用号SYS_creat,采用读写模式创建拷贝的新文件,若创建失败输出相应提示。

使用syscall()函数和系统调用号SYS_write,向新文件中写入读取的内容,若写入失败输出相应提示。

使用syscall()函数和系统调用号SYS_close,分别关闭两个文件,若关闭失败则分别输出相应提示。

若以上步骤均成功则最后输出相应拷贝成功提示。

4.3外部命令

4.3.1显示环境变量

该命令是采用直接调用exec系统调用实现的方式。

调用fork()函数生成子进程并返回pid,根据该值判断。

如果出现错误,fork返回一个负值,此时打印错误信息并返回;在子进程中,fork返回0,此时调用execlp()命令参数为“env”,即可显示所有的系统环境变量;在父进程中,fork返回新创建子进程的进程ID,需调用wait()函数等待。

该命令是采用直接调用exec系统调用实现的方式。

调用fork()函数生成子进程并返回pid,根据该值判断。

如果出现错误,fork返回一个负值,此时打印错误信息并返回;在子进程中,fork返回0,此时调用execlp()命令参数为“pstree-p”,即可以树状图显示一系列子进程;在父进程中,fork返回新创建子进程的进程ID,需调用wait()函数等待。

4.4系统环境变量支持

关键数据结构为自定义的结构体,结构体内为两字符型数组,分别用于存储系统环境变量的名称和变量的值。

该命令是间接调用相应的系统调用实现的方式。

关键算法是用户输入该命令后和系统环境变量的设置后,调用setenv()函数设置该环境变量并设置为可复写的,方便后续修改该变量的值。

同时,附加在本地变量中也保存了上述设置的系统环境变量。

在存储变量的数组中保存上述系统环境变量即可。

5编译运行测试结果

编译运行自行实现的命令解释程序shell.o,显示出命令输入提示符Qin>”,提示用户输入命令,如图1所示。

图1

5.1采用间接调用实现的内部命令

5.1.1显示指定目录下文件列表

用户输入命令ls后,指定具体的目录路径,可显示在该目录下的文件列表,并将文件编号显示,格式为“file编号:

文件名”,每行显示一个文件的文件名,如图2所示。

图2

5.1.2显示当前路径

用户输入命令pwd后,在下一行显示当前路径并回车换行。

如图3所示。

图3

5.1.3文件重命名

用户输入该命令rename后,在下一行显示“pleaceinputtheoldfilename:

”,用户需输入需要重命名的文件名,然后显示“pleaceinputthenewfilename:

”,用户需输入该文件的新的文件名,即可完成对文件的重命名并显示成功提示。

再次输出该目录下文件,可见文件已经重命名,如图4所示。

图4

5.1.4显示输入内容

用户输入该命令echo后,输入空格,然后输入需要显示的内容,即可在下一行显示上述用户希望输出的内容并回车换行。

如图5所示。

图5

5.1.5使用帮助

用户输入该命令help后,然后显示本命令解释程序的合法命令及其具体的功能说明。

如图6所示。

图6

5.1.6退出程序

用户输入该命令exit/quit后,显示“thankyouforusing!

bye~”,之

后该命令解释程序(Shell)退出到Linux操作系统上的原命令解释程序Shell。

如图7所示。

图7

5.1.7设置和初始化系统环境变量

此处略,详见下文5.4系统环境变量支持中的说明

5.2采用直接调用的内部命令

5.2.1文件拷贝

用户输入该命令copy后,然后显示“pleaceinputthefilenametobecopied:

”,用户输入需要复制的文件的文件名,然后显示“pleaceinputthenewfilename:

”,用户输入新拷贝文件的文件名,即可完成文件的拷贝。

再次输出该目录下文件,可见文件已经被拷贝,如图8所示。

 

图8

5.3外部命令

5.3.1显示环境变量

用户输入该命令environ后,然后显示出所有的系统环境变量,每行显示一个。

部分输出结果如图9所示。

 

5.3.2显示当前一系列进程用户输入该命令后,然后显示出当前一系列进程和子进程。

部分输出结果

如图10所示。

图10

5.4系统环境变量支持

用户输入该命令export后,然后输入需要设置的系统环境变量和变量值,格式为:

“[系统变量名称]=[系统变量值]”,若该系统环境变量没有设置过,则初始化该变量完成。

例如下例中初始化某系统环境变量为“test=9999”。

初始化完成后,使用“env”命令查看结果,系统环境变量已经初始化,输出结果如图11所示。

若该系统环境变量为曾经设置过,则修改该变量完成。

例如下例中设置系统环境变量为“test=998”。

设置完成后,使用“env”命令查看结果,系统环境变量已经重新设置,输出结果如图12所示。

htoMTNA禽MgMbl

TERM-3E『nl

SHELLPspbJl刍HISTS12^1.000strlHICI-HEMT■一盅JG^lrJflowos

QTDBt・>5fbG4/±u>«DI-DFkDW/rQob

JOTIzFfJb64/qT+UW二K1ude

SSH—TTY*/d霑/p議占use冒rgi-t

LAIg厂0RS・1・J?

chgr34二n"o!

r壬・34八4^畀・3774益:

0^3r?

/t耳・0r3rJt'e“?

卅-orw忙「gNI-oratrN-0r3*?

/xN-01:

:

血nmbor肯-•■N810H^wl:

*・n^^onoM-WH"*-7曲占一-一*Jcbm-ol»ln;-x^^drK'7・l.f&lu",-rt^?

rr法7・寸毛=01八芻:

•grn=ou爲7・总4当忙3洽*■01+31?

广AshQl一3i?

T*rHHO!

?

u5*;*2;01苍^"01135i*=OCXHO^-i35\.甜aAHol二®广au"ots'\一孟=Dr3E;"Qg由UQr3supx=0r就;"XMP-W-=O1iMA】LM>Jar27耳17

PATHb、UMmb64、qt—3・:

、uslvloca

PWD・、tg厂AMobeFUTUTF—«

〔SH_A3KPASS=0us『f二g*cc./apg5Mlvgnwnelssll—工ISTCO/1K0Ln」gn□redups

lAHd

HOME<「Q

QTLTBU>冷、=黑4>7十乂二b

2S』SH"誥丁劭H_CON址EmNulg^le严125LO3O4G14严16严LESSOPENJLAtwr^-in'iessp-ipF审h56s

G1BR0KENJ=HLENPMESM1

eabMgd

0^3V■

国11

nMftlHIJO-srtrtftErtMgga

V*3^

HOSTNAMEnbel/lVL

ter乔xtmrm

GHELL^ff-jrvbashHI5T5IET1000

QTD1亍>5r、二bEtQT3•3olop舀・7TOQr

Qdzc・>sr、-Hbmt£w・弋亠右ude

5l/lHITTV・、de<、prvt'osmsAsrt

厂FCOLOWSMrTFdFtm^lnMDr3严斗占口箱745?

-w=44x2-5甲37:

44不节0上32';・聶「莒1八31;■tgNMp7・dNdol;31';,g村m.汙占忙31;*xur丄賈:

OLm\・moo・em';・nB.o・Qr3r.*FNQr3上/Kbmol;w5:

.*xpfn-ol二5';•吐丁0T35:

・U工吕上rr3!

7.*■百"01:

3s:

/Qgn=CQws;・HP$Q!

:

3!

T*•Grul^Lsgl二穿nfou35+:

f2HQr735+;-k&r・!

?

QgK■呂«?

?

?

£・01^卑/311-0戸世6;-flxJMJrsd-wvorw«\.・JgxA-rs®?

兀拾诂・euE:

K4IL<.£r/%00=总ms^.

mu«trviibt4、QT3.3jb」n:

vMr二Qcal、3trln-;U2pwmp

LAluG-enlusNTFL

5SH_A$KPA5T'^sr、1ib鼻孟z、opmns0h<=n0mm・sU1U一H&TcohJTROL”」gnD&dup5

5HLC厂Hl

HOME<「合rf

LOGWAMEAQCII:

QTLIHHAJSr'IihMtQTg'

SGHICONZECTICN■一盅•16严一館•193096lgr*E68・一壁LE550PEh2、uwr*bltv」r>AMfnpr>.5h鎳GJBROKE厂FT厂EMA盂wtfphftl1#3②17281251eHvorsdnlunuHps

国12

 

以上功能均在在Linux操作系统上启用并测试验证通过,暂未发现错误。

6技术难点及解决方案

1)初次接触Linux操作系统,对于原命令解释程序shell的命令等并不熟悉。

对于设计与实现基于Linux内核的命令解释程序(Shell)有一定难度。

需首先熟悉原命令解释程序shell的使用方法和原理,再自行实现一个命令解释程序。

2)外部命令执行采用直接调用exec系统调用的方式。

Exec是一系列的函数,包括execl、execlp、execle、execv、execvp。

具体使用哪个来完成外部命令的功能,需要了解各个函数间的区别,联系和常用的用法。

3)系统环境变量支持的功能要求可以设置和初始化系统环境变量,如何完成该功能是一个难点。

该功能试图利用外部命令,调用原命令解释程序shell的export命令实现,但未能实现。

后利用内部命令的间接调用系统调用的方式通过setenv()函数实现。

7疑难解惑及经验教训

1)内部命令和外部命令的区分:

内部命令是命令解释程序直接解释执行的;外部命令是其他可执行程序支持的。

内部命令和外部命令的区分都是对于自行实现的命令解释程序shell,而不是原Linux操作系统上的命令解释程序shell。

2)直接调用系统调用和间接调用系统调用:

间接调用系统调用是用户进程调用C语言函数库中的函数来调用系统调用;直接调用系统调用是利用syscall()函数使用系统调用号来直接调用系统调用。

8结论与体会

本次Linux命令解释程序设计与实现实验成果总结如下:

1)设计和实现一组内部命令一共8条,实现典型内部命令的处理功能,包括:

ls,pwd,copy,rename,echo,help,export,exit/quit;

2)设计和实现外部命令一共2条,包括:

jobs,env。

执行采用直接调用exec系统调用的方式来实现;

3)一条内部命令copy采用直接调用相应系统调用的方式来实现,其他内部命令采用间接调用相应系统调用的方式来实现;

4)系统环境变量(至少包括当前目录)支持,通过export命令功能实现系统环境变量的设置和初始化;

5)在Linux操作系统上启用并测试验证,未发现错误;

6)命令提示符显示、命令辨别(区分内部命令与外部命令及不同内部命令)和执行处理;

通过本次Linux命令解释程序设计与实现实验,本人对于初次实操接触的Linux操作系统有了初步的了解。

特别是对于Linux操作系统的原命令解释程序的操作和一些典型命令的使用有了一定掌握。

通过对于Linux操作系统的原命令解释程序的学习,自行编写C语言程序设计实现自己的命令解释程序。

在过程中,学习了Linux系统上的C语言编辑、编译和与运行和具体一些C语言的头文件和函数库中的函数。

并且加深了本人对于理论课程中讲解的内部命令和外部命令,系统直接调用和间接调用系统调用等概念的理解。

最终,本人自行实现了基于Linux内核的命令解释程序(Shell),主要包括系统环境变量的设置和初始化、系统命令提示符显示、命令辨别解析(区分内部命令与外部命令及不同内部命令)、典型内部命令等处理功能,并在Linux操作系统上测试验证通过。

在实验报告内容中运行结果截图的适当位置中应有机融入了个人姓名、学号、计算机系统信息等凸显个人标记特征的信息。

9源程序文件及源码清单

shell.c文件源码如下:

#include"stdio.h"

#include"string.h"

#include"unistd.h"

#include"sys/types.h"

#include"sys/stat.h"

#include"sys/syscall.h"

#include"stdlib.h"

#include"dirent.h"

#include"stddef.h"

#include"fcntl.h"

#include"malloc.h"

#definebuffsize1024

#defineO_RDONLY00

#defineO_RW066

voidlist_();

voidpwd_();

voidcopy_();

voidrename_();

voidecho_();

voidhelp_();

intjobs_();

intenviron_();

voidexport_();

voidenv_store(charcommand2[]);

voidenv_export(charcommand2[]);

structval_struct

{

charname[50];

charvalue[50];

};

intenv_num=0;

char*env_arrary[256]={0};

externchar**environ;

intmain()

{

charcommand[100];

while

(1)

{

printf("Qin>");

scanf("%s",command);

if(strcmp(command,"ls")==0){list_();

}

els

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1