利用进程控制开发一个简单的minishell程序

步骤:

  1. 打印提示符,并且让用户输入一个指令
  2. 解析输入的指令,找到相应的可执行程序
  3. 创建子进程,子进程进行程序替换,来加载可执行程序
  4. 父进程进行程序等待,等待子进程结束
  5. 子进程结束,父进程从等待中返回,循环执行 1 
//minishell
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>    
#include<string.h>


#include<string>
#include<vector>


//自己封装的命令
//input 表示等待切分命令
//output 表示切分结果
//返回值 表示output中包含几个有效元素
int Split(char input[], char* output[]) {//std::vector<std::string>* output) {
	//借助 strtok 实现   网站 cplusplus 由详细介绍
	char* p = strtok(input, " ");
	int i = 0;
	while (p != NULL)
	{
		//printf("%s\n", p);  //切分的验证
	//	output->push_back(p);
		output[i] = p;
		++i;
		p = strtok(NULL, " ");
	}
	output[i] = NULL;//这个操作很容易忘记的
	return i;
}

//ls -l /
//argv[0] —>ls
//argv[1] —>ls -l
//argv[2] —> /
void CreatProcess(char* argv, int n){//(const std::vector<std::string>& argv,n){
	(void)n;
	//创建子进程
	pid_t ret = fork();
	//父进程进行进程等待,子进程进行程序替换
	if (ret > 0){
		//father
		//暂时这么写,正常shell是应该知道子程序退出码
		wait(NULL);
	}
	else if (ret == 0){
		//child
		ret = execvp(argv[0],argv);
		//if条件可以省略,exec成功了,肯定不会执行这个代码
		if (ret < 0 )
		{
			perror("exec");
			exit(0);
		}
	}else {
		perror("fork");
	}

}

int main(){

	while (1){
		//1.打印提示符
		printf("[ZHOU@zhouminishell ~]$ ");
		fflush(stdout);
		//2.用户输入一个指令
		char command[1024] = { 0 };
		scanf("%s", command);  //有问题
		//换gets
		gets(command);  //一次读取一行

		//这句是测试scanf 能否扫描整行数据
		printf("%s\n", command);
		//会发现遇到空格就不行,有问题  例如:ls -l   就有问题

		//3.解析指令,把我们要执行的哪个程序识别出来,那些是命令行参数识别出来
		//方法是:按照空格字符串切分。切分结果是字符串数组
		char argv[1024] = {0};
		 //std::vector<std::string> argv;
		int n = Split(command, &argv);

		//4.创建子进程,进行程序替换
		CreatProcess(argv,n);
	}

	system("pause");
	return 0;
}

minishell的改进:

  1. 自动获取用户名,主机名,当前路径。
  2. 需要支持 cd 命令(cd 修改的子进程的路径,对父进程不影响)。注:需要让父进程直接支持 cd,而不是创建子进程/程序替换,cd是内建命令。
  3. 支持定义一些命令的别名。(需要在程序中维护键值对这样的数据结构,std::map
  4. 支持管道
  5. 支持重定向

strtok的相关知识:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值