Use Python to create your own Shell (bottom)

Source: Internet
Author: User

in the previous article, we have created a shell main loop, sliced the command input, and executed the command through fork and exec. In this part, we will solve the remaining problems. First, the CD TEST_DIR2 command cannot modify our current directory. Second, we are still unable to gracefully exit from the shell.

Step 4: Built-in Commands

"CD Test_dir2 cannot modify our current directory" is correct, but in a sense it is also wrong. After executing the command, we are still in the same directory, in this sense, it is right. However, the directory has actually been modified, except that it was modified in the subprocess.

Remember when we forked (fork) a child process and then executed the command, the process of executing the command did not occur on the parent process. As a result, we just changed the current directory of the child process, not the parent process's directory.

The child process then exits, and the parent process continues to run under the unchanged directory.

Therefore, this type of command, which is related to the shell itself, must be a built-in command. It must be executed in the shell process instead of in the fork (forking).

CD

Let's start with the CD command.

We first create a builtins directory. Each built-in command is placed into this directory.

yosh_project|--yosh   |--builtins   |   | --__init__.py   |   | --cd.py   |--__init__.py   |--shell.py

In cd.py, we implement our own CD commands by using the system call Os.chdir.

Import osfrom yosh.constants import *def CD (args):    os.chdir (args[0])    return Shell_status_run

Note that we will return the shell's running state from the built-in function. So, to be able to continue using constants in the project, we move them to yosh/constants.py.

yosh_project|--yosh   |--builtins   |   | --__init__.py   |   | --cd.py   |--__init__.py   |--constants.py   |--shell.py

In constants.py, we put the state constants here.

Shell_status_stop = 0shell_status_run = 1

Now, our built-in CD is ready. Let's modify shell.py to handle these built-in functions.

... # # # import constants from yosh.constants import *### use hash map to store built-in function names and their references Built_in_cmds = {}def tokenize (string):    return Shlex.split (String) def execute (cmd_tokens):    # # # # # # # # # # Split command names and parameters from tuples    cmd_name = cmd_tokens[0]    Cmd_args = cmd_ Tokens[1:]    # # # If the command is a built-in command, use parameters to call the function if    cmd_name in Built_in_cmds:        return Built_in_cmds[cmd_name] (cmd_ args)    ...

We use a python dictionary variable built_in_cmds as the hash map (to store our built-in functions.) We extract the name and parameters of the command in the Execute function. If the command is shot in our hash map, the corresponding built-in function is called.

(Hint: built_in_cmds[cmd_name] Returns a function reference that can be called directly with a parameter. )

We're almost ready to use the built-in CD function. The final step is to add the CD function to the Built_in_cmds map.

We defined the Register_command function to add a built-in function to our built-in command hash map. Next, we define the INIT function and register the built-in CD function here.

Note This line of Register_command ("CD", CD). The first parameter is the name of the command. The second argument is a function reference. To enable the second parameter CD to refer to the CD function reference in yosh/builtins/cd.py, we must put the following line in the yosh/builtins/__init__.py file.

From YOSH.BUILTINS.CD Import *

So, in yosh/shell.py, when we import * from Yosh.builtins, we can get a CD function reference that has been imported by Yosh.builtins.

We've got the code ready. Let's try to run our shell,python-m Yosh.shell as a module in the Yosh sibling directory.

The CD command now correctly modifies our Shell directory, and the non-built commands still work. Very good!

Exit

The last piece finally came: gracefully withdrew.

We need a function that can modify the shell state to shell_status_stop. This way, the shell loop can end naturally and the shell will reach the end and exit.

As with CDs, if we fork in a subprocess and execute the Exit function, it does not work for the parent process. Therefore, the Exit function needs to be a shell built-in function.

Let's start with this: Create a new file named exit.py in the Builtins directory.

yosh_project|--yosh   |--builtins   |   | --__init__.py   |   | --cd.py   |   | --exit.py   |--__init__.py   |--constants.py   |--shell.py

exit.py defines an exit function that simply returns a state that can exit the main loop.

From yosh.constants import *def exit (args):    return Shell_status_stop

We then import the Exit Function reference that is located in the yosh/builtins/__init__.py file.

From YOSH.BUILTINS.CD import *from yosh.builtins.exit Import *

Finally, we register the exit command in the init () function in shell.py.

# # # # # # # # # # # # here to register all built-in Commands def init ():    Register_command ("CD", CD)    Register_command ("Exit", exit) ...

End

Try to execute python-m Yosh.shell. Now you can exit the program gracefully by typing exit.

The final idea

I want you to enjoy the process of creating Yosh (your own shell) as much as I do. But my Yosh version is still in its early stages. I did not deal with some extreme situations that would cause the shell to crash. There are many built-in commands that I don't have covered. To improve performance, some non-built-in commands can also be implemented as built-in commands (avoid new process creation time). At the same time, a large number of features have not been implemented (see common features and different features).

Now it's time to create the Shell you really own.
Happy coding!

This article reprinted address: http://www.linuxprobe.com/python-shell-create.html

Free to provide the latest Linux technology tutorials Books, for open-source technology enthusiasts to do more and better: http://www.linuxprobe.com/

Use Python to create your own Shell (bottom)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.