⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shell.cpp

📁 C语言编程实现了linux的shell功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	real_order[i]='\0';
	i++;
	if(flag_out==1&&input[i]=='>')
	{
		flag_out=2;
		i++;
	}
	else if (flag_in==1&&input[i]=='<')
	{
		flag_in=2;
		i++;
	}
	//读出前面的空格
	while ((input[i]==' '||input[i]=='	')&&i<len)
		i++;
	j=0;
	out_filename[0]='\0';
	in_filename[0]='\0';
	//读取定向输入或输出的文件
	if(flag_out>0)
	{	
		while (i<=len)
		{
			if(input[i]=='<')
			{
				out_filename[j]='\0';
				break;
			}
			out_filename[j]=input[i];
			i++;
			j++;
		}
	}
	if(flag_in>0)
		while (i<=len)
		{
			if (input[i]=='>')
			{
				in_filename[j]='\0';
				break;
			}
			in_filename[j]=input[i];
			i++;
			j++;
		}
	//既存在输出重定向也存在输入重定向
	if (i<len)
	{
		j=0;
		if (flag_out>0&&input[i]=='<')
		{
			i++;
			flag_in=1;
			if(input[i]=='>')
			{
				flag_in=2;
				i++;
			}
			//读出前面的空格
			while ((input[i]==' '||input[i]=='	')&&i<len)
				i++;
			while (i<=len)
			{
				in_filename[j]=input[i];
				i++;
				j++;
			}
		}
		else if (flag_in>0&&input[i]=='>')
		{
			i++;
			flag_out=1;
			if(input[i]=='>')
			{
				flag_out=2;
				i++;
			}
			//读出前面的空格
			while ((input[i]==' '||input[i]=='	')&&i<len)
				i++;
			while (i<=len)
			{
				out_filename[j]=input[i];
				i++;
				j++;
			}
		}
		else
		{
			fprintf(stderr,"ERROR!can't find the file!\n");
			return -1;
		}
	}
	
	//for debug
	/*printf("real_order: %s\n",real_order);
	printf("out_filename: %s\n",out_filename);
	printf("in_filename: %s\n",in_filename);*/

	k=number(real_order);
	analized_order=analize(real_order);//命令已经保存在*analized_order[]中
	if(strcmp(analized_order[0], "leave") == 0) //退出命令
	{
		printf("bye-bye\n");
		// 释放申请的空间
		for(i=0;i<k;i++)
			free(analized_order[i]);
		free(analized_order);
		free(real_order);
		exit(1);
		return 1;
	}

	/*如果输入的是cd命令*/
	if (strcmp(analized_order[0],"cd")==0)
	{
		do_cd(analized_order);
		// 释放申请的空间
		for(i=0;i<k;i++)
			free(analized_order[i]);
		free(analized_order);
		free(real_order);
		return 1;
	}
	order_path=is_file_exist(analized_order[0]);
	if(order_path==NULL)	//can't find the order
	{
		fprintf(stderr,"This is command is not founded ?!\n");
		// 释放申请的空间
		for(i=0;i<k;i++)
			free(analized_order[i]);
		free(analized_order);
		free(real_order);
		return -1;
	}
		//创建子进程用于执行命令
	if((pid = fork()) == 0) 
	{
		/* 存在输出输入重定向*/
	    if(flag_out==1)
			fd_out = open(out_filename,O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
		if(flag_out==2)
			fd_out = open(out_filename, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR );
		if(flag_in==1)
			fd_in = open(in_filename, O_RDONLY, S_IRUSR|S_IWUSR );
		if(flag_in==2)
			fd_in = open(in_filename, O_RDONLY, S_IRUSR|S_IWUSR );
        if(fd_out==-1) 
		{
			printf("Open out %s error \n", out_filename);
			return -1;
		}
		if(fd_in==-1) 
		{
			fprintf(stderr,"Open in %s error \n", in_filename);
			return -1;
		}
		  //使用dup2函数将标准输出重定向到fd_out上
		if(flag_out>0)
			if(dup2(fd_out, STDOUT_FILENO) == -1)
			{
				fprintf(stderr,"Redirect Standard Out Error !\n");
				exit(1);
			}
		  //使用dup2函数将标准输入重定向到fd_in上
		if(flag_in>0)
			if (dup2(fd_in,STDIN_FILENO)==-1)
			{
				fprintf(stderr,"Redirect Standard Out Error !\n");
				exit(1);
			}
		execv(order_path,analized_order);
		exit(1);		//子进程推出
	}
	else                     //父进程
	if(back==0)        // 并非后台执行指令
		pid=waitpid(pid, &status, 0);
	// 释放申请的空间
	free(out_filename);
	free(in_filename);
	free(order_path);
	for(i=0;i<k;i++)   
		free(analized_order[i]);
	free(analized_order);
	return 1;
}
int is_back(char *order)	//分析是否为后台进程,并且将字符&去掉
{
	int len=strlen(order);
	if(order[len]=='&')
	{
		order[len]='\0';
		return 1;
	}
	else return 0;
}
char *is_file_exist(const char *order)		//判断命令是否存在
{
	char * path, * p;
	char *buffer;
	int i,max_length;
	i = 0;
	/* 使用getenv函数来获取系统环境变量,用参数PATH表示获取路径*/
	path=getenv("PATH");
	p=path;
	max_length=strlen(path)+strlen(order)+2;
	if((buffer=(char *)malloc(max_length*(sizeof(char))))==0)
	{
		fprintf(stderr,"error! can't malloc enough space for buffer\n");
		return NULL;
	}
	while(*p != '\0') 
	{
	/* 路径列表使用":"来分隔路径*/
		if(*p != ':')  
			buffer[i++] = *p;
		else 
		{
		buffer[i++] = '/';
		buffer[i] = '\0';
		/* 将指令和路径合成,形成pathname,并使用access函数来判断该文件是否存在*/
		strcat(buffer,order);
		if(access(buffer,F_OK) == 0)     /* 文件被找到*/
			return buffer;
		else                          /* 继续寻找其他路径*/
			i=0;
		}
		p++;
	}
	/* 搜索完所有路径,依然没有找到则返回 NULL*/
	return NULL;
}

int number(const char *input)	//分析命令和参数数量,来划分相应字符串
{
	int i=0,k=0;
	int input_len=strlen(input);
	k=0;	//k记录命令和参数数量
	int flag=0;
	for (i=0;i<input_len;i++)
	{

		if(input[i]==' '||input[i]=='<'||input[i]=='>'||input[i]=='	')
		{
			flag=0;
			continue;
		}
		else 
		{
			if(flag==0)
			{
				flag=1;
				k++;
			}
		}
	}
	return k;
}
char **analize(const char *input)	//分析键入的命令,获取命令和参数并保存在arg中
{
	int number(const char *input);	//分析命令和参数数量,来划分相应字符串
	
	int i,j,k;	//k记录命令和参数数量
	int input_len;
	int is_back=0;

	char *buffer;
	char **arg;//存放命令及相应参数

	input_len=strlen(input);

	if((buffer=(char *)malloc((input_len+1)*(sizeof(char))))==0)
	{
		fprintf(stderr,"error! can't malloc enough space for buffer\n");
		return NULL;
	}
	
	//分析命令和参数数量
	k=number(input);
	if((arg=(char **)malloc((k+1)*sizeof(char *)))==0)
	{
		fprintf(stderr,"error! can't malloc enough space for arg\n");
		return NULL;
	}
	
	//将输入命令划分为相应命令和参数
	for (i=0,j=0,k=0;i<=input_len;i++)
	{
		if(input[i]==' '||input[i]=='<'||input[i]=='>'||input[i]=='	'||input[i]=='\0')
		{
			if(j == 0) /*这个条件可以略去连在一起的多个空格或者TAB */
				continue;
			else 
			{
				buffer[j] = '\0';
				j++;
				arg[k] = (char *)malloc(sizeof(char)*j);
				/* 将指令或参数从缓存拷贝到arg中*/
				strcpy(arg[k], buffer);
				j=0;  /* 准备去下一个参数*/
				k++;
			}
		}
		else 
		{   /* 如果字符串最后是 '&',则置后台运行标记为 1 */
			if(input[i]== '&' && input[i+1]=='\0') 
			{
				is_back = 1;
				continue;
			}
			buffer[j]=input[i];
			j++;
		}
	}
	/* 在使用exec执行命令的时候,最后的参数必须是NULL指针,所以将最后一个参数置成空值*/
	arg[k]=NULL;

	//释放申请空间
	free(buffer);
	return arg;
}
char *read_order(char *buffer)		//从键盘中读取命令
{
	char lc_char;
	char *input;
	int input_lenth=0;

	lc_char = getchar();
	while(lc_char != '\n' && input_lenth < BUFFERSIZE) 
		{
			buffer[input_lenth] = lc_char;
			lc_char = getchar();
			input_lenth++;
		}
	if(input_lenth >= BUFFERSIZE) //超过允许缓冲区最大长度则抱错退出
	{
		fprintf(stderr,"Your command too long ! Please reenter your command !\n");
		input_lenth = 0;     /* Reset */
		return NULL;
	}
	else  
	buffer[input_lenth] = '\0'; //加上串结束符,形成字符串
	if((input=(char *)malloc(sizeof(char)*(input_lenth+1)))==0)
	{
		fprintf(stderr,"error! can't malloc enough space for input\n");
		return NULL;
	}
	strcpy(input, buffer);
	return input;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -