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

进程程序替换

  • 替换原理
  • 替换函数
  • 实现一个简单的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[]);

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

实现一个简单的shell

主要过程

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

  1. 获取命令行-----fgets
  2. 解析命令行-----strtok
  3. 建立一个子进程(fork)
  4. 替换子进程(execvp)
  5. 父进程等待子进程退出(wait)
    [Linux] 进程程序替换之实现一个简单的shell_第1张图片

实现代码

#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;
	}

你可能感兴趣的:(Linux,linux,运维,服务器)