[Translate] Create your own shell:part II using Python

Source: Internet
Author: User

Use Python to create your own Shell:part II

[TOC]

Original link and description
    1. https://hackercollider.com/articles/2016/07/06/create-your-own-shell-in-python-part-2/
    2. This translation document is originally selected from Linux China , the translation of documents copyright belongs to linux China all

In Part 1, we have created a major shell loop, a segmented command input, and the passing fork and exec executing of commands. 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 fork a child process and execute the command, the process of executing the command does 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 without forking (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 commands by using system calls os.chdir cd .

import osfromimport*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.

=0=1

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

 ... # Import constants  from  yosh.constants import  *  # Hash map to store built-in function name and reference as key and value  Built_in_cmds =  {}def  tokenize (String): return  shlex.split (String) span class= "kw" >def  Execute (cmd_tokens): # Extract command name and arguments from Tokens Cmd_name =  cmd_tokens[0 ] Cmd_args =  cmd_to Kens[1 :] # If the command is a built-in command, invoke it function with Argu ments  if  cmd_name in  built_in_cmds: retu RN  Built_in_cmds[cmd_name] (Cmd_args) ...  

We use a python dictionary variable built_in_cmds as a hash map (hash map) to store our built-in functions. We execute extract the name and parameters of the command in the 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 that can be referenced directly using the argument call.) )

We're almost ready to use the built-in cd functions. The final step is cd to add the function to the built_in_cmds map.

...# Import all built-in function referencesfrom yosh.builtins import *...# Register a built-in function to built-in command hash mapdef register_command(name, func):    built_in_cmds[name] = func# Register all built-in commands heredef init():    register_command("cd", cd)def main():    # Init shell before starting the main loop    init()    shell_loop()

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.

Pay attention to this line register_command("cd", cd) . The first parameter is the name of the command. The second argument is a function reference. In order to be able to cd refer to yosh/builtins/cd.py the function reference in the second argument cd , we must place 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 yosh.builtins a function reference that has been imported cd .

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

Now the cd command can modify our shell directory correctly, and the non-built command will still work. Very good!

Exit

The last piece finally came: gracefully withdrew.

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

And cd , like, if we fork and execute functions in a child process exit , 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: builtins create a new file named under the directory exit.py .

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

exit.pyDefines a 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 yosh/builtins/__init__.py the function reference that is located in the file exit .

from yosh.builtins.cd import *from yosh.builtins.exit import *

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

...# Register all built-in commands heredef init():    register_command("cd", cd)    register_command("exit", exit)...

End

Attempt to execute python -m yosh.shell . Now you can enter exit gracefully to exit the program.

The final idea

I want you to enjoy yosh the process of creating (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 functions have not been implemented (see common features and different features)

I have provided the source code in the Github.com/supasate/yosh. Please feel free to fork and try.

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

Happy coding!

via:https://hackercollider.com/articles/2016/07/06/create-your-own-shell-in-python-part-2/

[Translate] Create your own shell:part II using Python

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.