Heim > Backend-Entwicklung > Python-Tutorial > So erstellen Sie Ihre eigene Shell mit Python (Teil 2)

So erstellen Sie Ihre eigene Shell mit Python (Teil 2)

巴扎黑
Freigeben: 2017-03-18 11:54:37
Original
1197 Leute haben es durchsucht

Im vorherigen Artikel haben wir eine Shell-Hauptschleife erstellt, die Befehlseingabe aufgeteilt und den Befehl über fork und exec ausgeführt. In diesem Teil werden wir uns mit den verbleibenden Problemen befassen. Erstens kann der Befehl cd test_dir2 unser aktuelles Verzeichnis nicht ändern. Zweitens können wir die Shell immer noch nicht ordnungsgemäß verlassen.

Schritt 4: Integrierter Befehl

cd test_dir2 kann unser aktuelles Verzeichnis nicht ändern“ Dieser Satz ist richtig, aber in gewissem Sinne auch falsch. Es ist in dem Sinne richtig, dass wir uns nach der Ausführung des Befehls immer noch im selben Verzeichnis befinden. Das Verzeichnis wurde jedoch tatsächlich geändert, jedoch im untergeordneten Prozess.

Denken Sie daran, dass wir einen untergeordneten Prozess gegabelt und dann den Befehl ausgeführt haben. Der Prozess zur Ausführung des Befehls fand nicht im übergeordneten Prozess statt. Das Ergebnis ist, dass wir nur das aktuelle Verzeichnis des untergeordneten Prozesses ändern, nicht das Verzeichnis des übergeordneten Prozesses.

Dann wird der untergeordnete Prozess beendet, während der übergeordnete Prozess im intakten Verzeichnis weiterläuft.

Daher müssen solche Befehle, die sich auf die Shell selbst beziehen, integrierte Befehle sein. Es muss im Shell-Prozess und nicht im Forking ausgeführt werden.

cd

Beginnen wir mit dem Befehl cd.

Wir erstellen zunächst ein builtins-Verzeichnis. Jeder integrierte Befehl wird in diesem Verzeichnis abgelegt.

yosh_project
|-- yosh
   |-- builtins
   |   |-- __init__.py
   |   |-- cd.py
   |-- __init__.py
   |-- shell.py
Nach dem Login kopieren

In cd.py implementieren wir unseren eigenen os.chdir-Befehl, indem wir den Systemaufruf cd verwenden.

import os
from yosh.constants import *
def cd(args):
    os.chdir(args[0])
    return SHELL_STATUS_RUN
Nach dem Login kopieren

Beachten Sie, dass wir den Betriebsstatus der Shell von der integrierten Funktion zurückgeben. Um Konstanten weiterhin im Projekt verwenden zu können, haben wir sie nach yosh/constants.py verschoben.

yosh_project
|-- yosh
   |-- builtins
   |   |-- __init__.py
   |   |-- cd.py
   |-- __init__.py
   |-- constants.py
   |-- shell.py
Nach dem Login kopieren

In constants.py haben wir hier alle Zustandskonstanten eingefügt.

SHELL_STATUS_STOP = 0
SHELL_STATUS_RUN = 1
Nach dem Login kopieren

Jetzt ist unser eingebautes cd fertig. Ändern wir shell.py, um diese integrierten Funktionen zu verarbeiten.

...
### 导入常量
from yosh.constants import *
### 使用哈希映射来存储内建的函数名及其引用
built_in_cmds = {}
def tokenize(string):
    return shlex.split(string)
def execute(cmd_tokens):
    ### 从元组中分拆命令名称与参数
    cmd_name = cmd_tokens[0]
    cmd_args = cmd_tokens[1:]
    ### 如果该命令是一个内建命令,使用参数调用该函数
    if cmd_name in built_in_cmds:
        return built_in_cmds[cmd_name](cmd_args)
    ...
Nach dem Login kopieren

Wir verwenden eine Python-Wörterbuchvariable built_in_cmds als Hash-Map, um unsere integrierten Funktionen zu speichern. Wir extrahieren den Namen und die Parameter des Befehls in der Funktion execute. Befindet sich der Befehl in unserer Hash-Map, wird die entsprechende integrierte Funktion aufgerufen.

(Tipp: built_in_cmds[cmd_name] gibt eine Funktionsreferenz zurück, die direkt mit Argumenten aufgerufen werden kann.)

Wir sind fast bereit, die integrierte Funktion cd zu verwenden. Der letzte Schritt besteht darin, die Funktion cd zur Zuordnung built_in_cmds hinzuzufügen.

...
### 导入所有内建函数引用
from yosh.builtins import *
...
### 注册内建函数到内建命令的哈希映射中
def register_command(name, func):
    built_in_cmds[name] = func
### 在此注册所有的内建命令
def init():
    register_command("cd", cd)
def main():
    ###在开始主循环之前初始化 shell
    init()
    shell_loop()
Nach dem Login kopieren

Wir definieren die Funktion register_command, um unserer integrierten Befehls-Hash-Map eine integrierte Funktion hinzuzufügen. Als nächstes definieren wir die Funktion init und registrieren die integrierte Funktion cd hier.

Achten Sie auf diese Zeile register_command("cd", cd) . Der erste Parameter ist der Name des Befehls. Der zweite Parameter ist eine Funktionsreferenz. Damit der zweite Parameter cd auf die Funktionsreferenz yosh/builtins/cd.py in cd verweisen kann, müssen wir die folgende Codezeile in die Datei yosh/builtins/__init__.py einfügen.

from yosh.builtins.cd import *
Nach dem Login kopieren

Wenn wir also in yosh/shell.py yosh.builtins aus * importieren, können wir die yosh.builtins-Funktionsreferenz erhalten, die über cd importiert wurde.

Wir haben den Code bereit. Versuchen wir, unsere Shell yosh als Modul im selben Verzeichnis wie python -m yosh.shell auszuführen.

Jetzt ändert der Befehl cd korrekt unser Shell-Verzeichnis, während nicht integrierte Befehle weiterhin funktionieren. sehr gut!

Ausstieg

Das letzte Stück ist endlich da: elegant aussteigen.

Wir benötigen eine Funktion, die den Shell-Status in SHELL_STATUS_STOP ändern kann. Auf diese Weise kann die Shell-Schleife auf natürliche Weise enden und die Shell erreicht das Ende und verlässt sie.

ist dasselbe wie cd. Wenn wir die Funktion exit im untergeordneten Prozess verzweigen und ausführen, hat dies keine Auswirkungen auf den übergeordneten Prozess. Daher muss die Funktion exit eine in die Shell integrierte Funktion sein.

Beginnen wir hier: Erstellen Sie eine neue Datei mit dem Namen builtins im Verzeichnis exit.py.

yosh_project
|-- yosh
   |-- builtins
   |   |-- __init__.py
   |   |-- cd.py
   |   |-- exit.py
   |-- __init__.py
   |-- constants.py
   |-- shell.py
Nach dem Login kopieren

exit.py definiert eine exit-Funktion, die nur einen Status zurückgibt, der die Hauptschleife verlassen kann.

from yosh.constants import *
def exit(args):
    return SHELL_STATUS_STOP
Nach dem Login kopieren

Dann importieren wir die yosh/builtins/__init__.py-Funktionsreferenz, die sich in der exit-Datei befindet.

from yosh.builtins.cd import *
from yosh.builtins.exit import *
Nach dem Login kopieren

Zuletzt registrieren wir den Befehl shell.py in der Funktion init(). exit

...
### 在此注册所有的内建命令
def init():
    register_command("cd", cd)
    register_command("exit", exit)
...
Nach dem Login kopieren
Das ist es!

Versuchen Sie, python -m yosh.shell auszuführen. Jetzt können Sie exit eingeben, um das Programm ordnungsgemäß zu beenden.

Abschließende Gedanken

Ich hoffe, dass Ihnen die Erstellung genauso viel Spaß gemacht hat wie mir yosh (Ihrunserem >ellen) Prozess. Aber meine Version von steckt noch in den Kinderschuhen. Ich habe mich nicht mit einigen Eckfällen befasst, die die Shell zum Absturz bringen würden. Es gibt viele integrierte Befehle, die ich nicht behandelt habe. Um die Leistung zu verbessern, können einige nicht integrierte Befehle auch als integrierte Befehle implementiert werden (um Zeit für die Erstellung neuer Prozesse zu sparen). Gleichzeitig sind zahlreiche Features noch nicht implementiert. Ich habe den Quellcode unter https://github.com/supasate/yosh bereitgestellt. Bitte zögern Sie nicht, es zu forken und auszuprobieren. yoshJetzt ist es an der Zeit, eine Hülle zu erstellen, die wirklich zu Ihnen passt.

Viel Spaß beim Codieren!

Das obige ist der detaillierte Inhalt vonSo erstellen Sie Ihre eigene Shell mit Python (Teil 2). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage