# **一、引言**
**程序名称:**Linux简单命令解释器
**开发语言:**C
**开发平台:**MacOS
**开发工具:**CLion
**程序说明:**已实现基本命令,如:pwd、ls、cd、mkdir和exit命令。
**运行环境:**MacOS
**文件说明:**程序源代码(main.c、FileSystem.h);
程序数据文件(FileSystem.img);
# **二、需求分析**
Linux/UNIX系统中,shell是用户和系统内核沟通的中介,它为用户使用操作系统的服务提供了一个命令界面。用户在命令提示符($或是#)下输入的每一个命令都由shell解释,然后传给内核执行。
对于我们的题目,在Linux环境下模拟实现简单命令解释器,根据题目要求,我分析后得出,此课程设计主要是在我们熟悉linux基础操作的基础上能够学以致用,编写一个简单的模拟shell命令解释器,以使我们能够理解linux命令的执行过程。
# **三、程序概要设计**
## **1.主要功能**
根据题目要求,我们需要实现的基本命令包括:
pwd //显示当前所在目录的路径名
list <目录名> //列出指定目录名中的所有目录及文件
cd <目录名或路径> //改变当前工作目录
mkdir <目录名> //新建目录
exit //退出命令解释程序
## 2.程序流程图
**![](img/Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.001.png)程序流程图**
# **四、程序详细设计**
## **(一)文件系统设计**
在本次课程设计中,我通过模拟文件管理系统来实现模拟Linux的终端操作。文件目录结构采用了Unix的树形目录结构,如下图:
![](img/Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.002.jpeg "1-140F1163124E6")
### **1.核心思想**
本程序的核心思想是一切皆是文件。如果是目录,Block中存储的是目录下文件和目录的fcb;如果是文件,Block中存储的是文件的内容。
### **2.文件系统结构详细设计**
*文件系统块(超级块)结构:*
```c
typedef struct {
unsigned short blockSize;
unsigned int blockNum;
unsigned int iNodeNum;
unsigned int blockFree;
} SuperBlock;
```
其中blockSize是文件块大小、blockNum是文件块数量、iNodeNum* 是inode节点数量,即文件数量、blockFree是空闲块数量。
*文件inode节点结构:*
```c
typedef struct {
unsigned int id;
char name[30];
unsigned char isDir;
unsigned int parent;
unsigned int length;
unsigned int blockId;
} INode, *PtrINode;
```
其中id是* inode节点索引、name是文件名,最大长度29、isDir是文件类型, 0为file 1为dir、parent是父目录inode节点索引、length是文件长度,目录文件则为子文件项数量、blockId是文件项所在的目录数据块的id。
*文件部分信息节点,用于简要显示文件信息(如:文件名、文件/目录、文件长度、文件权限和修改时间等)。主要用途:将一个目录下的所有文件(包括目录)写入到该目录对应的Block中*
```c
typedef struct {
unsigned int id;
char name[30];
unsigned char isDir;
unsigned int blockId; //4B,在目录数据块中的位置0-255
} Fcb, *PtrFcb;
```
这部分的变量在INode节点结构都有,就不多做解释了。
还有两个使用图:
```c
char *blockBitmap;
char *iNodeBitmap;
```
其中,blockBitmap是文件块使用图,块分配情况;iNodeBitmap* 是iNode节点使用图,索引节点分配情况
### **3.初始化文件系统**
宏定义了一些数值:
```c
#define BLOCK_SIZE 1024 // 块大小
#define BLOCK_NUM 102400 // 块数量
#define INODE_NUM 102400 // inode节点数
#define SYSTEM_NAME "FileSystem.img" //数据(文件系统镜像)文件名
```
创建文件系统:
先通过fopen以写入二进制的方式打开FileSystem.img文件(即创建该img文件),若打开失败则退出程序:
```c
if ((fp = fopen(SYSTEM_NAME, "wb+")) == NULL) {
printf("open file %s error...\n", SYSTEM_NAME);
exit(1);
}
```
然后初始化两个使用图:
```c
for (len = 0; len < BLOCK_NUM; len++)
blockBitmap[len] = 0;
for (len = 0; len < INODE_NUM; len++)
iNodeBitmap[len] = 0;
```
再设置创建文件系统所需的内存:
```c
for (len = 0; len < (superBlockSize + blockBitmapSize + inodeBitmapSize + inodeSize * INODE_NUM +
BLOCK_SIZE * BLOCK_NUM); len++) {
fputc(0, fp); // 往缓冲区填充0
}
```
后面再通过fseek函数把文件指针移到对应信息存储位置的头部,再用fwrite函数和把初始化后的超级块、INode节点和使用图等写入文件中。下面是文件块使用图写入到文件举例:
```c
fseek(fp, superBlockSize, SEEK_SET);
fwrite(blockBitmap, blockBitmapSize, 1, fp);
```
打开文件系统:
同样先通过fopen以二进制读写的方式打开文件,这里就不贴代码了。
然后通过fread把文件系统的基本使用信息(如超级块和使用图)读入到内存中。
以下是读取超级块信息的举例:
```c
fread(&superBlock, superBlockSize, 1, fp);
```
## **(二)命令详细设计**
### **1.pwd**
该功能显示当前所在目录的路径名,运行如下图所示:
![](img/Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.003.png)
图4-1 pwd运行截图
核心代码:
```c
fullPath = malloc(sizeof(char));
strcpy(fullPath, curINode->name); // 临时存当前路径
while (curINode->id != 0) {
fseek(fp, superBlockSize + blockBitmapSize + inodeBitmapSize + curINode->parent * inodeSize, SEEK_SET);
fread(curINode, inodeSize, 1, fp);
if (strcmp(curINode->name, "/") != 0) {
fullPath = stringJoin( "/", fullPath);
fullPath = stringJoin(curINode->name, fullPath);
}
}
if (fullPath[0] != '/') {
fullPath = stringJoin( "/", fullPath);
fullPath = stringJoin(fullPath, "/");
}
```
分析:
定义一个char数组fullPath,并存下当前文件(夹)名。然后用一个for循环读取inode节点的父节点,每读到一个父节点,就取该父节点的文件(夹)名添加到fullPath的前面,直到根目录为止。
### **2.list**
该功能显示当前所在目录或传入的目录下的所有文件夹和文件,运行如下图所示:
![](img/Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.004.png)
图4-2 list运行截图
核心代码:
先通过fseek函数把文件指针移到当前目录的inode节点头部,然后读取当前目录的inode信息,以便获取到下一步要用到当前目录的Block Id:
```c
fseek(fp, superBlockSize + blockBitmapSize + inodeBitmapSize + currentDir * inodeSize, SEEK_SET);
fread(parentInode, inodeSize, 1, fp);
```
同样,先根据上面获取到的Block Id把文件指针移到对应的节点头部,
```c
fseek(fp, superBlockSize + blockBitmapSize + inodeBitmapSize + inodeSize * INODE_NUM +
parentInode->blockId * BLOCK_SIZE, SEEK_SET);
```
然后for循环遍历该Block下的所有文件fcb,直到读完最后一个文件为止(由文件数length控制)。
```c
for (i = 0; i < parentINode->length; i++)
fread(fcb, fcbSize, 1, fp);
```
### **3.cd**
该功能用于改变当前工作目录,运行如下图所示:
![](img/Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.005.png)
图4-3 cd运行截图
核心代码:
注:
1. 函数原型:**void** cd(**char** \*name);
2. 当前目录用一个无符号短整型的变量currentDir表示,指的是当前所在目录的节点号。
程序先判断传入的路径名name是否为**".."**,若是则直接从文件读入当前目录的inode节点信息,以获取到父目录从而改变当前路�
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
Linux/UNIX系统中,shell是用户和系统内核沟通的中介,它为用户使用操作系统的服务提供了一个命令界面。用户在命令提示($或是#)下输入的每一个命令都由shell解释,然后传给内核执行。对于我们的题目,在Linux环境下模拟实现简单命令解释器,根据题目要求,我分析后得出,此课程设计主要是在我们熟悉linux基础操作的基础上能够学以致用,编写一个简单的模拟shell命令解释器,以使我们能够理解linux命令的执行过程。
资源推荐
资源详情
资源评论
收起资源包目录
100012648-基于C开发的Linux简单命令解释器.zip (16个子文件)
cos-coursedesign
CMakeLists.txt 153B
src
main.c 288B
Doc
说明书.doc 595KB
~$说明书.doc 162B
《操作系统课程设计》题目.doc 16KB
LICENSE 1KB
img
Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.006.png 40KB
Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.008.png 14KB
Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.003.png 61KB
Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.004.png 17KB
Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.002.jpeg 34KB
Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.005.png 45KB
Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.007.png 43KB
Aspose.Words.92f07349-ada2-4c3a-8c31-a2888624a192.001.png 103KB
head
FileSystem.h 14KB
README.md 12KB
共 16 条
- 1
资源评论
神仙别闹
- 粉丝: 3758
- 资源: 7468
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功