操作系统实验:简单 shell 命令行解释器的设计与实现
#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);
int i, j = 0;
char str[100];
char s[100];
memset(str,0,sizeof(str)); // 清除str数组
memset(s,0,sizeof(s)); // 清除s数组
int flag = 1;
fgets(str, 100, stdin);
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",strpwd);
memset(sr,0,sizeof(sr)); // 清除sr数组
}
}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 2:environ\n");
printf("3:echo 4:help\n");
printf("5:jobs 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;
}
我在shell.c这个文件的同一目录下创建了text这个文件夹,当文件夹存在时,chdir()函数返回0,这里看到第一张图片也就打印出来0,当我再次执行此命令时,由于没有此文件夹(hakhgka)故下一张图片打印出了-1,并且我们可以看到当前的目录已经转到了text的文件夹下了。
PS:使用memset();函数,在下次调用cd()函数时将数组清空以达到像输入两个点(.)这样返回上级目录的效果。