【Linux】Simple shell

       Shell: In simple terms, it is the intermediate medium used by the system to interact with computer hardware. It is only a tool of the system . In fact, there is another layer between the shell and the computer hardware that is the system kernel . The shell essentially replaces the process program.

Replacement principle:

           After creating a child process with fork, it executes the same program as the parent process (but it may execute a different code branch). The child process often calls an exec function to execute another program. When a process calls an exec function, the user space code and data of the process are completely replaced by the new program, and execution begins with the new program's startup routine. Calling exec does not create a new process, so the id of the process does not change before and after calling exec.

Replace function:

        There are six functions that begin with exec, collectively referred to as exec functions:

#include<unistd.h>

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[]);

Function explanation:

     1. If these functions are called successfully, the new program will be loaded and executed from the startup code, not returning.

      2. Return 1 if there is an error in the call.

      3. Therefore, the exec function has only an error return value and no successful return value.

Naming Comprehension:

      1. l(list): Indicates 
      the parameter list 2. v(vector): Array 
      for parameters 3. p(path): there is p to automatically search for the environment variable PATH 
      4. e(env): Indicates that it maintains the environment variable by itself

Implementation of shell:

The shell reads the string "ls" from the user, the shell creates a new process, then runs the ls program in that process and waits for that process to finish.


So to write a shell, you need to loop the following process: 
(1) get the command line 
(2) parse the command line 
(3) create a subprocess (fork) 
(4) replace the subprocess (execvp) 

(5) The parent process waits for the child process to exit (wait)

Following these ideas, implement a simple shell:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
#include<string.h>

char *argv[8];
int argc = 0;
	void do_parse(char *buf)
{
	int i;
	int status = 0;
	for(argc=i=0;buf[i];i++){
	
		if(!isspace(buf[i]) &&status == 0){
		
			argv[argc++] = buf + i;
			status = 1;
		}else if(isspace(buf[i])){
		
			status = 0;
			buf[i] = 0;
		}	
	}
	argv[argc] = NULL;
}

void do_execute(void)
{
	pid_t pid = fork();
	switch(pid){
	
		case -1:
		perror("fork");
		exit(EXIT_FAILURE);
		break;
		case 0:
		execvp(argv[0],argv);
		perror("execvp");
		exit(EXIT_FAILURE);
		default:
		{
			int st;
			while(wait(&st) != pid)
				;
		}
	}
}
	int main(void)
{
	char buf[1024]  = {};
	while(1){
	
		printf("myshell>:");
		scanf("%[^\n]%*c",buf);
		do_parse(buf);
		do_execute();
	}
}

测试结果:



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324530516&siteId=291194637