Operating system - implement a simple shell command line interpreter

1: Experimental questions

Implement a simple shell command line interpreter

2: Experimental purpose

The main purpose of this experiment is to further learn how to use process-related system calls under the Linux system and understand the working of the shell .

The basic principle is to design a command interface for the Linux operating system by yourself .

Three: Overall design (including background knowledge or basic principles and algorithms, or module introduction, design steps, etc.)

The shell to be designed is similar to sh, bash, csh, etc., and must support the following internal commands:

cd <directory> changes the current working directory to another <directory>. If <directory> is not specified, the current working directory is output. like

If <directory> does not exist, there should be an appropriate error message. This command should also change the PWD environment variables.

environ lists the settings of all environment variable strings (similar to the env command under Linux systems).

echo <content> displays the content after echo and breaks the line

help outputs a brief summary of how to use your shell and its basic functions.

Jobs outputs the shell's current series of child processes. The name and PID number of the child process must be provided.

quit,exit,bye exit the shell.

Background knowledge and rationale:

Shell is a command line interpreter that provides an interactive interface between the user and the operating system. The shell receives commands entered by the user, interprets and executes them, and returns the results to the user. Shell plays a connecting role in the operating system. It can call various functions and services of the system. It is also a window for users to interact with the operating system.

Design steps:

1. Read the command line entered by the user.

2. Parse the command line, separate commands and parameters, and perform corresponding syntax checks.

3. Perform corresponding operations according to the parsed command. This can be calling a system built-in command, executing an external program, or performing a range of other operations.

4. Process the results of command execution and output the results to the user.

5. Repeat the above steps until the user chooses to exit.

Specific module introduction:

Input module: responsible for reading the command line entered by the user.

Parsing module: Responsible for parsing the command line, separating commands and parameters, and performing syntax checking.

Execution module: execute corresponding operations according to the parsed command. This may involve calling system built-in commands, executing external programs, etc.

Output module: processes the results of command execution and outputs the results to the user.

Main control module: cyclically executes the above modules to control the entire command line interpreter process.

Design steps:

*Design data structures, such as command structures, parameter lists, etc.

*Implement the input module to read the command line entered by the user.

*Implement the parsing module to parse the command line into commands and parameters, and perform syntax checking.

*Implement the execution module to perform corresponding operations according to the parsed command.

*Implement the output module to process the results of command execution and output the results to the user.

*Implement the main control module, execute the input, parsing, execution and output modules cyclically, and control the entire command line interpreter process.

*Conduct testing and debugging to ensure the command line interpreter is functioning properly.

*Optimize and improve as needed, adding additional functionality or features.

Through the above steps, you can implement a simple shell command line interpreter. In actual operation, users can enter various commands, such as viewing files, creating directories, executing programs, etc. The interpreter will parse and execute these commands and return the execution results to the user.

Four: Detailed design (including main data structures, program flow charts, key codes, etc.)

Main code:

char cmd[2100];

    while(1)

    {

        printf( "Please enter the operation:" );

        scanf("%s",cmd);

        int len=strlen(cmd),i;

        if(cmd[0] == 'e' && cmd[1] == 'c') // echo

        {

            int flag=0;

            for( i=5; i<len-1; i++)

            {

                if(cmd[i]!=' ') flag=1;

                if(flag)

                {

                    putchar(cmd[i]);

                }

            }

            if(flag) putchar('\n');

        }

        else if(cmd[0]=='q' || cmd[1]=='x' || cmd[0]=='b') // quit,exit,bye

        {

            printf("Bye\n");

            return 0;

        }

        else if(cmd[0]=='h') // help

        {

            printf("/**********************************/\n");

            printf("echo <content>\tprint a line content\n");

            printf("quit,exit,bye\tend produce\n");

            printf("cd <catalog>\techo catalog\n");

            printf("jobs\techo process name and pid...\n");

            printf("environ\techo environment variable\n");

            printf("/**********************************/\n");

        }

        else

        {

            char cata[100];

            int cnt=0;

            if(cmd[0]=='c') // cd

            {

                int flag=0;

                for( i=3; i<len; i++)

                {

                    if(cmd[i]!=' ') flag=1;

                    if(flag)

                    {

                        cata[cnt++] = cmd[i];

                    }

                }

                if(cnt==0)

                {

                    cata[0]='.';

                    cata[1]='\0';

                }

            }

            /* fork a child process */

            pid_t pid = fork();

            if (pid < 0)

            {

                /* error occurred */

                fprintf(stderr, "Fork Failed");

                return  1 ;

            }

            else if(pid==0)

            {

                if(cmd[0]=='c') // cd

                {

                    execlp("/bin/ls",cata,NULL);

                }

                else if(cmd[0]=='j') // jobs

                {

                    execlp("pstree","-p",NULL);

                }

                else if(cmd[0]=='e') // environ

                {

                    execlp("env","",NULL);

                }

            }

            else

            {

                /* wait wait,until child process exit*/

                wait();}

        }

        printf("\n");

    }

return 0;

Five: Experimental results and analysis

This code is a simple command line interpreter program that accepts commands entered by the user and performs corresponding operations. Here are the results and analysis of the experiment on the code:

 

 

The main loop of the program uses an infinite loop that continuously receives user input and processes commands.

When the user enters a command starting with "ec", the program will print out the content except the previous part (that is, the content after "ec"). This function is similar to the echo command and can display the input content on the screen.

When the user enters a command starting with "q", "x", or "b", the program prints "Bye" and exits.

When the user enters a command starting with "h", the program prints a series of help messages, including descriptions of the available commands.

For other commands starting with the letter "c", the program will create a child process to perform the corresponding operation. The specific operations vary depending on the command:

If the command starts with "cd", the child process will call the execlp function to execute the /bin/ls command to display the contents of the specified directory.

If the command starts with "j", the child process will call the execlp function to execute the pstree -p command to display the process tree and information about related processes.

If the command starts with "e", the child process will call the execlp function to execute the env command to display information about the environment variables.

The parent process will wait for the child process to complete execution, and then continue with the next cycle.

To sum up, this code is a simple command line interpreter that has basic functions, but there is also some room for improvement and potential problems. Actual experimental results and analysis will depend on the specific commands and actions you enter when running the code.

6. Summary and experience

This code is a basic command line interpreter program that implements some common command operations, such as printing content, exiting the program, displaying help information, executing system commands, etc.

1. The code uses a loop structure to enable the program to continuously receive user input and process commands, enhancing interactivity.

2. The fork and execlp functions are used to create and execute the child process, making full use of the process management and external command execution functions provided by the operating system.

3. There are potential problems with some functions in the code, such as incomplete input validation and bounds checking, and the way subprocess creation and waiting can be handled more robustly. These problems can be solved by improving the code to improve the robustness and security of the program.

4. During the experiment, you can try different commands and parameters to test the function and correctness of the program, and observe whether the output and behavior of the program are as expected.

5. This code provides us with a basic framework that can be further expanded and improved as needed, adding more functions and commands to meet actual needs.

Guess you like

Origin blog.csdn.net/CSH__/article/details/131383128