linuxshell源代码,Linux简单shell实现(附源代码).doc
Linux下Shell的实现说明⽂档
作业⼀实验要求:
Shell能够解析的语法为:
commandline := pipecommand | pipecommand "&" commandline | empty
pipecommand := redirectcommand | pipecommand "|" redirectcommand
redirectcommand := command ">" outfile |
command "
command "" outfile |
command ">" outfile "
command
command := program | command argument
需求说明和分析:
本作业要求为实现⼀个类似于bash的shell。要求⽀持后台命令,管道,重定向这三个基本功能。并在此基础上,实现⼀些简单的内部命令,例如cd,pwd等等。
设计⽅案:
⾸先利⽤readline()函数读到⽤户输⼊的shell命令,采⽤⼀个数组来保存shell命令,数组有固定的⼤⼩。
在main()函数中根据字符串中是否存在 "&" 字符判断是否为后台进程。如果是后台命令则判断是否是多条指令,如果不是将分割后的命令传递给pipel()函数,如果是的话分割之后利⽤while循环将命令传递给pipel()函数。如果不是后台进程,需要⽤waitpid()函数等待⼦进程结束后⽗进程才继续。
在pipel()函数中,将shell命令根据 "|" 字符分割成⼀个个重定向命令,利⽤fork ()得到⼦进程,并完成管道的设置,然后对每个重定向命令调⽤redirect()函数(如果没有 "|",则将整个shell命令调⽤redirect()函数)。
shell代码在redirect函数⾥⾯,根据有没有”>”,”
3、储存结构
1、帮助⽂档的结构,⽅便Help命令的构建。
struct HELP_DOC {
char *usage[lengthOfBUILTIN_COMMANDS]; //⽤法
char *info[lengthOfBUILTIN_COMMANDS]; //介绍
};
2、后台命令管理链表的结构,⽤于jobs指令的后台储存。
typedef struct BACK_JOBS {
pid_t pid;//记录进程名的pid
char *cmd;
int status;//三种状态 0为DONE 1为RUNNING 2为STOPPED
}BACK_JOB;
3、History命令需要的数据的链表节点结构
typedef struct Node {
int id;
char cmd[100]; //储存每条打过的命令
struct Node *next;
} NODE;
4、shell基本功能的实现难点
1、管道的实现
管道输出核⼼代码为:
order = trim(strtok(cmd, "|"));
other = trim(strtok(NULL, ""));
if (!other)
redirect(order);
else {
pipe(&fd[0]);
if ((pid = fork()) == 0) {
close(fd[0]);
close(STD_OUT);
dup(fd[1]);
close(fd[1]);
redirect(order);
} else {
close(fd[1]);
close(STD_IN);
dup(fd[0]);
close(fd[0]);
waitpid(pid, &status, 0);
pipel(other);
}}
关闭管道输⼊端,将标准输出重定向到管道输出,然后关闭管道输出。管道输⼊的核⼼代码也是类似的。
输⼊输出重定向
⾸先判断是否有输⼊输出重定向,⽤标志记录,我把类型分为6种,根据这六种不同的类型,进⾏不同的重定向的⽅法。然后在以下核⼼代码中实现重定向,即把标准输⼊输出定向到指定的⽂件。
if (type == 4 || type == 5 || type == 6) {
if ((fd_out = creat(outfile, 0755)) == -1

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。