Linux下模拟实现一个微型shell

首先我们先看一下shell的运行过程:

     

        shell从用户读入字符串"ls",并建立一个新的进程,在那个进程中运行ls程序并等待那个进程结束。然后shell读取新的一行输入,建立一个新的进程,在这个进程中运行程序并等待这个进程结束。

所以我们要写一个微型shell,需要循环以下过程:

  1.  获取终端输入。
  2.  解析输入(按空格解析到一个一个的命令参数)。
  3. 创建一个子进程,在子进程中进行程序替换,让子进程运行命令。
  4. 等待子进程运行完毕,收尸,获取退出状态码。

根据这个思路和我们之前学习到的知识,就可以自己实现一个微型shell了。

来看代码(使用Linux操作系统实现):

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

int argc;
char *argv[32];
int param_parse(char *buff)
{
	// ls -l
	if (buff == NULL)
		return -1;
	char *ptr = buff;
	char *tmp = ptr;
	argc = 0;
	while ((*ptr) != '\0')
	{
		//当遇到空格,并且下一个位置不是空格的时候,将空格位置置位为'\0'
		//然后用argv[argc]来保存这个字符串的位置
		if ((*ptr) == ' ' && *(ptr + 1) != ' ')
		{
			*ptr = '\0';
			argv[argc] = tmp;
			tmp = ptr + 1;
			argc++;
		}
		ptr++;
	}
	argv[argc++] = tmp;
	argv[argc] = NULL;
	return 0;
}

int exec_cmd()
{
	int pid = 0;
	pid = fork();
	if (pid < 0)
		return -1;
	else if (pid == 0)
	{
		execvp(argv[0], argv);
		exit(0);
	}
	//父进程在这里必须等待子进程退出,来看看子进程为什么退出了,是不是出现了什么错误。
	//通过获取状态码,并且转换一下退出码所对应的错误信息进行打印。
	int statu;
	wait(&statu);
	//判断子进程是否代码运行完毕退出
	if (WIFEXITED(statu))
	{
		//获取到子进程的退出码,转换为文本信息打印。
		printf("%s\n", strerror(WEXITSTATUS(statu)));
	}
	return 0;
}

int main()
{
	while (1)
	{
		printf("mashell> ");
		char buff[1024] = { 0 };
		// %[^\n]  获取数据直到遇到\n为止
		// %*c     清空缓冲区,数据都不要了
		scanf("%[^\n]%*c", buff);
		printf("%s\n", buff);
		param_parse(buff);
		exec_cmd;
	}
	return 0;
}

 测试结果:

  

猜你喜欢

转载自blog.csdn.net/ENSHADOWER/article/details/83215523
今日推荐