• [Linux] 进程程序替换之实现一个简单的shell


    替换原理

    1. 用fork创建子进程后执行的是和父进程相同的程序,若要执行不同的代码分支,子进程往往要调用一种exec函数以执行另一个程序;
    2. 当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行;
    3. 调用exec函数并不创建新进程,所以调用exec前后该进程的id并未改变。

    替换函数

    有六种以exec开头的函数,统称exec函数

    int execl(const char *path, const char *arg, ...);
    int execlp(const char *file, const char *arg, ...);
    int execle(const char *path, const char *arg, ...,char *const envp[]);
    int execv(const char *path, char *const argv[]);
    int execvp(const char *file, char *const argv[]);
    int execve(const char *path, char *const argv[], char *const envp[]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其中,l(list) 表示参数采用列表,v(vector) 表示参数用数组,p(path) 表示有p自动搜索环境变量PATH,e(env) 表示自己维护环境变量。

    实现一个简单的shell

    主要过程

    一个简单的shell,需要循环以下过程:

    1. 获取命令行-----fgets
    2. 解析命令行-----strtok
    3. 建立一个子进程(fork)
    4. 替换子进程(execvp)
    5. 父进程等待子进程退出(wait)
      shell的过程

    实现代码

    #define SIZE 64
    #define NUM 16
    
    int main(){
    	char cmd[SIZE];
    	const char* cmd_line = "[gxr116@Centos_7 lesson2_1]$ ";
    	while(1){
    		cmd[0] = 0;
    		printf("%s", cmd_line);
    		fgets(cmd, SIZE, stdin);  //命令行参数通过标准输入写入cmd
    		printf("%s", cmd);
    		cmd[strlen(cmd)-1] = '\0';  //把换行符替换为结束标志\0
    
    		char* argv[NUM];  //定义一个字符串数组,用来存放解析的结果
    		argv[0] = strtok(cmd, " ");  //以空格来分割字符串,把第一个子串放在argv[0]中
    		int i= 1;
    		do{
    			argv[i] = strtok(NULL, " ");  //分割剩下的字符串
    			if(argv[i] == NULL){
    				break;
    			}
    			i++;
    		}while(1);
    
    		//测试命令行参数是否能被正确解析
    		/*
    		int j = 0;
    		for( ; j
    
    		pid_t id = fork();
    		if(id == 0){	//child:命令行解析
    			execvp(argv[0], argv);  //执行进程程序替换,替换成功,则不再返回
    			exit(1); //替换失败,则程序退出
    		}
    		else if(id > 0){	//father:等待子进程退出
    			int status = 0;
    			pid_t ret = waitpid(id, &status, 0);
    			if(ret > 0){
    				printf("status code: %d\n", (status>>8)&0xff);
    			}
    		}
    		else{
    			perror("fork error!\n");
    		}
    		return 0;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
  • 相关阅读:
    python自动合成图片为gif,并能根据第一张图片自动统一图片尺寸
    Java 21 新特性:switch的模式匹配
    Mac 一键禁用自带键盘 使用外接键盘
    1024节日快乐
    深度学习YOLOv4环境配置
    基于OSATE环境的AADL项目——简单的项目构建与分析示例
    合肥工业大学计算机考研资料汇总
    加速可编程创新,2023年英特尔FPGA中国技术日披露全矩阵FPGA产品与应用方案
    github遇到想要强制拉取远程仓库内容
    面试官:说说TCP如何实现可靠传输
  • 原文地址:https://blog.csdn.net/Darling_sheeps/article/details/128086158