简易shell的实现

/* 自主minishell实现
*		1、获取标准输入
*		2、解析输入得到[命令名] + [运行参数]
*		3、创建子进程
*		    子进程中进行程序替换
*		4、进程等待
*/

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

int main()
{
	while(1)
	{
//获取字符串
		char buf[1024] = {0};
		printf("[uesr@localhost]$ ");
		fflush(stdout);
		//%[^\n]  从缓冲区取数据的时候,遇到\n为止[      ls    -l]
		//经过这一步后,缓冲区中留下了\n,但是\n取不出来,导致scanf非阻塞
		//但又取不出最后的\n字符
		//%*c      从缓冲区中取出一个字符(丢弃)
		if(scanf("%[^\n]%*c", buf) != 1)  //scanf给几个空间分配内容(赋值)就返回几
		{
			//若在输入状态多按几次空格
			//解析失败,缓冲区中还存在一个回车字符未取出来
			getchar();
			continue;

		}
		printf("buf:[%s]\n", buf);
//解析
		int argc = 0;
		char* argv[32];
		char* ptr = buf;
		while(*ptr != '\0')
		{
			//将指针走到非空白字符处
			if(!isspace(*ptr))  //不是空白字符
			{
				argv[argc] = ptr;
				argc++;
				//将ls走完,认为ls是一个完整的字符串
				//不能仅仅将l字符串作为第0个参数
				while(!isspace(*ptr) && *ptr != '\0')
				{
					ptr++;
				}
				//在ls之后添加一个字符串结尾标志
				//因为我们想获取的是ls,而不是[ls    -l     ]
				*ptr = '\0';
				printf("argv[%d] = %s\n", argc, argv[argc - 1]);
			}
			ptr++;
		}
		//argv[] = {"ls", "-l", NULL,}
		argv[argc] = NULL;

//实现shell内建命令
		if(strcmp(argv[0], "cd") == 0)
		{
			//int chdir(const char* path);
			//改变当前工作路径
			chdir(argv[1]);
			continue;
		}

//实现shell命令
		int pid = fork();
		if(pid < 0)
		{
			perror("fork error");
			return -1;
		}
		else if(pid == 0)
		{
			//进程替换
			execvp(argv[0], argv);
			exit(-1);
		}
		//进程等待--避免僵尸进程
		wait(NULL);

	}
	return 0;
}
发布了67 篇原创文章 · 获赞 15 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_43746320/article/details/102537159
今日推荐