操作系统课设 简单 shell 命令行解释器的设计与实现

操作系统课设 简单 shell 命令行解释器的设计与实现

1、实验目的

本实验主要目的在于进一步学会如何在 Linux 系统下使用进程相关的系统调用,了解 shell 工作的基本原理, 自己动手为 Linux 操作系统设计一个简单的命令接口。

2、背景知识

本实验要使用创建子进程的 fork()函数,执行新的命令的 exec()系列函数,通常 shell 是等待子进程结束后再接受用户新的输入,这可以使用 waitpid()函数。以上相关的系统函数调用的说明请参见实验二的背景知识。

3、设计内容与要求
要设计的 shell 类似于 sh,bash,csh 等,必须支持以下内部命令:

  1. cd<目录>更改当前的工作目录到另一个<目录>。如果<目录>未指定,输出当前工作目录。如果<目录>不存在,应当有适当的错误信息提示。这个命令应该也能改变
    PWD 的环境变量。
  2. environ 列出所有环境变量字符串的设置(类似于 Linux 系统下的 env 命令)。
  3. echo <内容 > 显示 echo 后的内容且换行
  4. help 简短概要的输出你的 shell 的使用方法和基本功能。
  5. jobs 输出 shell 当前的一系列子进程,必须提供子进程的命名和 PID 号。
  6. quit,exit,bye 退出 shell。

提示: shell 的主体就是反复下面的循环过程
while(1){
接收用户输入的命令行;
解析命令行;
if(用户命令为内部命令)
直接处理;
else if(用户命令为外部命令)
创建子进程执行命令;
else
提示错误的命令;
}

注意:linux上创建一个文件,复制下面代码,改文件名为.c编译运行即可.

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
//help方法
void help()
{
	char str[100];
	scanf("%s", str);
	if(strcmp("help", str) == 0){
		printf("cd <目录>更改当前的工作目录到另一个<目录>\n");
		printf("environ 列出所有环境变量字符串的设置\n");
		printf("echo <内容 > 显示 echo 后的内容且换行\n");
		printf("help 简短概要的输出你的 shell 的使用方法和基本功能\n");
		printf("jobs 输出 shell 当前的一系列子进程,必须提供子进程的命名和 PID 号\n");
		printf("quit,exit,bye 退出 shell\n");
	}else
		printf("程序错误!\n");
}

//quit||exit||bye退出方法
void quit()
{
	char str[100];
	scanf("%s", str);
	if(strcmp("quit", str) == 0 || strcmp("exit", str) == 0 || strcmp("bye", str) == 0)
	{
		printf("shell 命令行解释器模拟结束!\n");
		_exit(0);
	}else
		printf("程序错误!\n");
}

//cd跳转目录方法
void cd()
{
	char sr[100];	
	
	char strpwd[301];
    	memset(strpwd,0,sizeof(strpwd));//出释怀数组函数
    	getcwd(strpwd,300);//获取当前工作目录字符串放到strpwd的前300个位置上
    	
	int i, j = 0;
	char str[100];
	char s[100];
	int flag = 1;
	fgets(str, 100, stdin);//获取输入的IO流 (命令行上的一行输入)
	if(str[0] == 'c' && str[1] == 'd')
	{
		for(i = 3; i < strlen(str) ; i++)
		{
			if(str[i] == ' ')
			{
				flag = 0;
				break;
			}else
				s[j++] = str[i];
		}
		for(i = 0; i < strlen(s) - 1; i++)
			sr[i] = s[i];
			
		if(flag == 0)
			printf("当前目录是:%s\n",strpwd);
		if(flag == 1)
		{
			
			printf("%d ", chdir(sr));
			printf("当前目录是:%s\n",getcwd(strpwd,300));
		}
		
	}else
		printf("程序错误!\n");
}

//environ显示环境变量字符串的设置
void environ()
{
	char str[100];
	fgets(str, 100, stdin);
	pid_t pid = fork();
	if(str[0] == 'e' && str[1] == 'n' && str[2] == 'v')
	{
		
		if(pid == 0)
			execlp("env", "", NULL);
		if(pid > 0)
			wait(NULL);
	}
}

//echo显示内容方法
void echo()
{
	int i;
	char str[100];
	fgets(str, 100, stdin);
	if(str[0] == 'e' && str[1] == 'c' && str[2] == 'h' && str[3] == 'o')
	{
		for(i = 5; i < strlen(str); i++){
			putchar(str[i]);
		}
		printf("\n");
	}else
		printf("程序错误!\n");
}

//jobs显示子进程
void jobs()
{
	char str[100];
	fgets(str, 100, stdin);
	pid_t pid = fork();
	if(str[0] == 'j' && str[1] == 'o' && str[2] == 'b' && str[3] == 's')
	{
		if(pid ==0)
		{
			execlp("pstree", " ", "-p", NULL);
		}
		if(pid > 0)
			wait(NULL);	
	}
}


int main()
{
	int t;
	while(1)
	{
		printf("-----------_-------_------\n");
		printf(" shell 命令行解释器 \n");
		printf("1:cd\n");
		printf("2:environ\n");
		printf("3:echo\n");		
		printf("4:help\n");
		printf("5:job\n");		
		printf("6:quit||exit||bye\n");
		printf("__------__----__---___--___--__-\n");
		printf("请输入你要执行的操作:\n");
		scanf("%d", &t);
		switch(t){
			case (1):
			getchar();
			cd();
				break;
			case (2):
			getchar();
			environ();
				break;
			case (3):
			getchar();
			echo();
				break;
			case (4):
			getchar();
			help();
				break;
			case (5):
			getchar();
			jobs();
				break;
			case (6):
			getchar();
			quit();
				break;
		}
	}
	return 0;
}	

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值