In Entwicklung Letztes Updateated:
Teilen:
Jira-Software ist das Projektmanagement-Tool Nr. 1, das von agilen Teams zum Planen, Verfolgen, Freigeben und Unterstützen großartiger Software verwendet wird.

SubprocessDamit können Sie jederzeit interagierenally neue Ebene mit dem Betriebssystem.

Unser Computer läuft unterprocessEs ist die ganze Zeit. Tatsächlich führen Sie allein durch das Lesen dieses Artikels eine Menge aus processEs ist wie ein Netzwerkmanager oder das Internet browsähmself.

Das Coole daran ist, dass jede Aktion, die wir auf unserem Computer ausführen, das Aufrufen eines Subs beinhaltetprocess. Das bleibt auch dann wahr, wenn wir ein einfaches schreiben "Hallo Welt" Skript in python.

Das Konzept der untenprocess mag unklar erscheinen, selbst wenn Sie schon eine Weile Programmieren lernen. Dieser Artikel befasst sich eingehend mit dem Hauptkonzept des Subsprocessund wie man Python verwendet untenprocess Standardbibliothek.

Am Ende dieses Tutorials werden Sie:

  • Verstehen Sie das Konzept von Subprocess
  • Habe die Grundlagen des Python-Sub gelerntprocess Bibliothek
  • Übte deine Python-Fähigkeiten mit nützlichen Beispielen

Lassen Sie uns darauf eingehen

Das Konzept von subprocess

Im Großen und Ganzen ein U-Bootprocess ist eine Computer process CREated von einem anderen process.

Wir können uns einen Sub vorstellenprocess als Baum, in dem jeder Elternteil process hat Kind processEs läuft hinterher. Ich weiß, dass das ziemlich verwirrend sein kann, aber sehen wir es uns anhand einer einfachen Grafik an.

Es gibt verschiedene Möglichkeiten, wie wir das visualisieren können process läuft auf unserem Computer. Unter UNIX (Linux und MAC) haben wir zum Beispiel htop, Das ist interaktiv process Zuschauer.

Der Baummodus ist das nützlichste Werkzeug, um einen Blick auf das laufende U-Boot zu werfenprocesses. Wir können aktiv werdenate es mit F5.

Wenn wir uns den Befehlsabschnitt genau ansehen, können wir die Struktur erkennen processEs läuft auf unserem Computer.

htop process Struktur
Alles beginnt mit / sbin / init Das ist der Befehl, der jeden startet process auf unserem Computer. Von diesem Punkt aus können wir den Beginn des Anderen erkennen processes gefällt xfce4-Screenshoter und dem xfce4-Terminal (Was zu noch mehr Sub führtprocess)

Einen Blick darauf werfen Windows, wir haben das Mythische Task-Manager Dies ist nützlich, wenn Sie diese abstürzenden Programme auf unserem Computer beenden.

Jetzt haben wir ein glasklares Konzept. Mal sehen, wie wir sub implementieren könnenprocesses in Python.

Subprocesses in Python

Ein U-Bootprocess In Python handelt es sich um eine Aufgabe, die ein Python-Skript delegiertates an das Betriebssystem (OS).

Die subprocess Mit der Bibliothek können wir Sub ausführen und verwaltenprocesses direkt aus Python. Dabei wird mit der Standardeingabe gearbeitet stdin, Standardausgabe stdoutund Rückkehrcodes.

Wir müssen es nicht mit PIP installieren, da es Teil von Python ist Standardbibliothek.

Daher können wir mit der Verwendung von Sub beginnenprocesses in Python einfach durch Importieren des Moduls.

import subprocess

# Using the module ....

Hinweis: Um diesem Artikel folgen zu können, sollten Sie Python 3.5 + haben

Zu Überprüfen Sie die Python-Version Sie derzeit haben, laufen Sie einfach.

❯ python --version
Python 3.9.5 # My result

Wenn die Python-Version 2.x ist, können Sie den folgenden Befehl verwenden

python3 --version

Weiter zum Thema, der Hauptidee hinter dem Subprocess Die Bibliothek soll in der Lage sein, mit dem Betriebssystem zu interagieren, indem sie beliebige Befehle direkt vom Python-Interpreter aus ausführt.

Das heißt, wir können was tunatever wir wollen, solange unser Betriebssystem es uns erlaubt (und solange Sie Ihr Root-Dateisystem nicht entfernen 😅).

Lassen Sie uns sehen, wie Sie es verwenden, indem Sie ein einfaches Skript erstellen, das die Dateien des aktuellen Verzeichnisses auflistet.

Erstes U-Bootprocess Anwendung

Lassen Sie uns zunächst erstellenate eine Datei list_dir.py. Dies ist die Datei, in der wir experimentieren werden, um Dateien aufzulisten.

touch list_dir.py

Öffnen wir nun diese Datei und verwenden den folgenden Code.

import subprocess 

subprocess.run('ls')

Zuerst importieren wir das Subprocess Modul und verwenden Sie dann die Funktion Lauf was läuft, der Befehl, den wir als Argument übergeben.

Diese Funktion wurde in Python 3.5 als benutzerfreundliche Verknüpfung zu eingeführt untenprocess.Popen. Die subprocessMit der Funktion .run können wir einen Befehl ausführen und warten, bis er abgeschlossen ist, im Gegensatz zu Popen, wo wir die Möglichkeit haben, communic aufzurufenate later.

Apropos Code-Ausgabe, ls ist eine UNIX-Befehl Hier werden die Dateien des Verzeichnisses aufgelistet, in dem Sie sich befinden. Wenn Sie diesen Befehl ausführen, wird eine Liste der im aktuellen Verzeichnis vorhandenen Dateien angezeigt.

❯ python list_dir.py
example.py  LICENSE  list_dir.py  README.md

Hinweis: Bedenken Sie das, wenn Sie dabei sind Windows, Sie müssen verschiedene Befehle verwenden. Zum Beispiel statt zu verwenden "Ls"  du kannst benutzen "Dir"

Das mag zu einfach erscheinen, und Sie haben Recht. Sie möchten die gesamte Leistung, die Ihnen die Shell bietet, voll ausschöpfen. Lassen Sie uns also lernen, wie man mit sub Argumente an die Shell übergibtprocess.

Um beispielsweise auch die versteckten Dateien (die mit einem Punkt beginnen) und alle Metadaten der Dateien aufzulisten, schreiben wir den folgenden Code.

import subprocess

# subprocess.run('ls')  # Simple command

subprocess.run('ls -la', shell=True)

Wir führen diesen Befehl als Zeichenfolge aus und verwenden das Argument Schale. Das bedeutet, dass wir zu Beginn der Ausführung unseres Subs eine Shell aufrufenprocess, und das Befehlsargument wird direkt von der Shell interpretiert.

Allerdings ist die Verwendung shell = True hat viele Nachteile, und das Schlimmste sind die möglichen Sicherheitslücken. Sie können darüber in der lesen offizielle Dokumentation.

Der beste Weg, Befehle an die Ausführungsfunktion zu übergeben, besteht darin, eine Liste zu verwenden, in der lst [0] ist der aufzurufende Befehl (in diesem Fall ls) und lst [n] sind die Argumente dieses Befehls.

In diesem Fall sieht unser Code folgendermaßen aus.

import subprocess

# subprocess.run('ls')  # Simple command

# subprocess.run('ls -la', shell=True) # Dangerous command

subprocess.run(['ls', '-la'])

Wenn wir die Standardausgabe eines Subs speichern möchtenprocess In einer Variablen können wir dies tun, indem wir das Argument „capture_output“ auf „true“ setzen.

list_of_files = subprocess.run(['ls', '-la'], capture_output=True)

print(list_of_files.stdout)

❯ python list_dir.py 
b'total 36\ndrwxr-xr-x 3 daniel daniel 4096 may 20 21:08 .\ndrwx------ 30 daniel daniel 4096 may 20 18:03 ..\n-rw-r--r-- 1 daniel daniel 55 may 20 20:18 example.py\ndrwxr-xr-x 8 daniel daniel 4096 may 20 17:31 .git\n-rw-r--r-- 1 daniel daniel 2160 may 17 22:23 .gitignore\n-rw-r--r-- 1 daniel daniel 271 may 20 19:53 internet_checker.py\n-rw-r--r-- 1 daniel daniel 1076 may 17 22:23 LICENSE\n-rw-r--r-- 1 daniel daniel 216 may 20 22:12 list_dir.py\n-rw-r--r-- 1 daniel daniel 22 may 17 22:23 README.md\n'

Um auf die Ausgabe von a zuzugreifen processverwenden wir das Instanzattribut stdout.

In diesem Fall möchten wir die Ausgabe als Zeichenfolge anstelle von Bytes speichern. Dazu können Sie das Textargument auf true setzen.

list_of_files = subprocess.run(['ls', '-la'], capture_output=True, text=True)

print(list_of_files.stdout)

❯ python list_dir.py
total 36
drwxr-xr-x  3 daniel daniel 4096 may 20 21:08 .
drwx------ 30 daniel daniel 4096 may 20 18:03 ..
-rw-r--r--  1 daniel daniel   55 may 20 20:18 example.py
drwxr-xr-x  8 daniel daniel 4096 may 20 17:31 .git
-rw-r--r--  1 daniel daniel 2160 may 17 22:23 .gitignore
-rw-r--r--  1 daniel daniel  271 may 20 19:53 internet_checker.py
-rw-r--r--  1 daniel daniel 1076 may 17 22:23 LICENSE
-rw-r--r--  1 daniel daniel  227 may 20 22:14 list_dir.py
-rw-r--r--  1 daniel daniel   22 may 17 22:23 README.md

Perfekt, jetzt wo wir die Grundlagen der kennen untenprocess Bibliothek, es ist Zeit, zu einigen Verwendungsbeispielen überzugehen.

Anwendungsbeispiele für subprocess in Python

In diesem Abschnitt werden wir Folgendes tun revSehen Sie sich einige praktische Anwendungen des Subs anprocess Bibliothek. Sie können sie alle hier überprüfen Github-Repository.

Programmprüfer

Eine der Hauptanwendungen dieser Bibliothek ist die Möglichkeit, einfache Betriebssystemoperationen durchzuführen.

Zum Beispiel ein einfaches Skript, das prüft, ob ein Programm installiert ist. Unter Linux können wir dies mit dem tun welche Befehl.

'''Program checker with subprocess'''

import subprocess

program = 'git'

process = subprocess. run(['which', program], capture_output=True, text=True)

if process.returncode == 0: 
    print(f'The program "{program}" is installed')

    print(f'The location of the binary is: {process.stdout}')
else:
    print(f'Sorry the {program} is not installed')

    print(process.stderr)

Hinweis: Wenn unter UNIX ein Befehl erfolgreich ist, lautet sein Statuscode 0. Sonstigeswise, bei der Ausführung ist etwas schief gelaufen

Da wir das nicht benutzen shell = True Argument können wir die Benutzereingaben sicher nehmen. Wir können auch überprüfen, ob die Eingabe ein gültiges Programm mit einem Regex-Muster ist.

import subprocess

import re

programs = input('Separe the programs with a space: ').split()

secure_pattern = '[\w\d]'

for program in programs:

    if not re.match(secure_pattern, program):
        print("Sorry we can't check that program")

        continue

    process = subprocess. run(
        ['which', program], capture_output=True, text=True)

    if process.returncode == 0:
        print(f'The program "{program}" is installed')

        print(f'The location of the binary is: {process.stdout}')
    else:
        print(f'Sorry the {program} is not installed')

        print(process.stderr)

    print('\n')

In diesem Fall erhalten wir die Programme vom Benutzer und verwenden einen regulären Ausdruck, der bestätigt, dass die Programmzeichenfolge nur Buchstaben und Ziffern enthält. Wir überprüfen die Existenz jedes Programms mit einer for-Schleife.

Hinweis: Überprüfen Sie dies Online-Regex-Tester.

Einfaches Grep in Python

Dein Freund Tom hat eine Liste von Mustern in einer Textdatei und eine andere große Datei, in der er die Anzahl der Übereinstimmungen für jedes Muster erhalten möchte. Er würde Stunden damit verbringen, das zu leiten grep Befehl für jedes Muster.

FortunatelySie wissen, wie Sie dieses Problem mit Python lösen können, und Sie werden ihm helfen, diese Aufgabe in wenigen Sekunden zu erledigen.

import subprocess

patterns_file = 'patterns.txt'
readfile = 'romeo-full.txt'

with open(patterns_file, 'r') as f:
    for pattern in f:
        pattern = pattern.strip()

        process = subprocess.run(
            ['grep', '-c', f'{pattern}', readfile], capture_output=True, text=True)

        if int(process.stdout) == 0:
            print(
                f'The pattern "{pattern}" did not match any line of {readfile}')

            continue

        print(f'The pattern "{pattern}" matched {process.stdout.strip()} times')

Wenn wir uns diese Datei ansehen, definieren wir zwei Variablen, die die Dateinamen sind, mit denen wir arbeiten möchten. Dann öffnen wir die Datei, die alle Muster und Iter enthältate über ihnen. Als nächstes rufen wir einen Sub aufprocess das führt einen grep-Befehl mit dem aus "-C" Flag (bedeutet Anzahl) und bestimmen Sie die Ausgabe der Übereinstimmung mit einer Bedingung.

Wenn Sie diese Datei ausführen (denken Sie daran, dass Sie die Textdateien von der herunterladen können Github Repo)

Richten Sie eine virtuelle Umgebung mit Sub einprocess

Eines der coolsten Dinge, die Sie mit Python machen können, ist process Automatisierung. Mit dieser Art von Skript können Sie jede Woche Stunden Zeit sparen.

Zum Beispiel werden wir create ein Setup-Skript, das erstellt wirdatesa virtuelle Umgebung für uns und versucht, eine zu finden requirements.txt Datei im aktuellen Verzeichnis, um alle Abhängigkeiten zu installieren.

import subprocess

from pathlib import Path


VENV_NAME = '.venv'
REQUIREMENTS = 'requirements.txt'

process1 = subprocess.run(['which', 'python3'], capture_output=True, text=True)

if process1.returncode != 0:
    raise OSError('Sorry python3 is not installed')

python_bin = process1.stdout.strip()

print(f'Python found in: {python_bin}')

process2 = subprocess.run('echo "$SHELL"', shell=True, capture_output=True, text=True)

shell_bin = process2.stdout.split('/')[-1]

create_venv = subprocess.run([python_bin, '-m', 'venv', VENV_NAME], check=True)

if create_venv.returncode == 0:
    print(f'Your venv {VENV_NAME} has been created')

pip_bin = f'{VENV_NAME}/bin/pip3'

if Path(REQUIREMENTS).exists():
    print(f'Requirements file "{REQUIREMENTS}" found')
    print('Installing requirements')
    subprocess.run([pip_bin, 'install', '-r', REQUIREMENTS])

    print('Process completed! Now activate your environment with "source .venv/bin/activate"')

else:
    print("No requirements specified ...")

In diesem Fall verwenden wir mehrere processes und Parsen der Daten, die wir in unserem Python-Skript benötigen. Wir verwenden auch die Pfadlib Bibliothek, die es uns ermöglicht, es herauszufinden, wenn die requirements.txt Datei existiert.

Wenn Sie die Python-Datei ausführen, erhalten Sie einige nützliche Meldungen darüber, was mit dem Betriebssystem passiert.

❯ python setup.py 
Python found in: /usr/bin/python3
Your venv .venv has been created
Requirements file "requirements.txt" found
Installing requirements
Collecting asgiref==3.3.4 .......
Process completed! Now activate your environment with "source .venv/bin/activate"

Beachten Sie, dass wir die Ausgabe der Installation erhalten process weil wir die Standardausgabe nicht in eine Variable umleiten.

Führen Sie eine andere Programmiersprache aus

Wir können andere Programmiersprachen mit Python ausführen und die Ausgabe aus diesen Dateien erhalten. Dies ist möglich, weil der SubprocessEs interagiert direkt mit dem Betriebssystem.

Lassen Sie uns zum Beispiel create ein Hallo-Welt-Programm in C++ und Java. Um die folgende Datei auszuführen, müssen Sie sie installieren C + + und Javac Compiler.

halloworld.cpp

#include <iostream>

int main(){
    std::cout << "This is a hello world in C++" << std::endl;
    return 0;
}


halloworld.java

class HelloWorld{  
    public static void main(String args[]){  
     System.out.println("This is a hello world in Java");  
    }  
}  


Ich weiß, dass dies im Vergleich zu einem einfachen Python-Einzeiler viel Code zu sein scheint, aber dies dient nur zu Testzwecken.

Wir werden Create ein Python-Skript, das alle C++- und Java-Dateien in einem Verzeichnis ausführt. Dazu möchten wir zunächst eine Liste der Dateien abhängig von der Dateierweiterung erhalten Klacks ermöglicht es uns, es einfach zu machen!

from glob import glob

# Gets files with each extension
java_files = glob('*.java')

cpp_files = glob('*.cpp')

Danach können wir mit der Verwendung von sub beginnenprocesses, jeden Dateityp auszuführen.

for file in cpp_files:
    process = subprocess.run(f'g++ {file} -o out; ./out', shell=True, capture_output=True, text=True)
    
    output = process.stdout.strip() + ' BTW this was runned by Python'

    print(output)

for file in java_files:
    without_ext = file.strip('.java')
    process = subprocess.run(f'java {file}; java {without_ext}',shell=True, capture_output=True, text=True)

    output = process.stdout.strip() + ' A Python subprocess runned this :)'
    print(output)

Ein kleiner Trick ist die Verwendung der String-Funktion abstreifen um die Ausgabe zu ändern und nur das zu bekommen, was wir brauchen.

Hinweis: Seien Sie vorsichtig, wenn Sie große Java- oder C ++ - Dateien ausführen, da wir deren Ausgabe in den Speicher laden und dies zu einem Speicherverlust führen kann.

Öffnen Sie externe Programme

Wir können andere Programme ausführen, indem wir einfach den Speicherort ihrer Binärdateien über ein Sub aufrufenprocess.

Probieren wir es aus, indem wir es öffnen trotzen, mein bevorzugtes Web browser.

import subprocess

subprocess.run('brave')

Dadurch wird ab geöffnetrowser-Instanz oder einfach eine andere Registerkarte, wenn Sie das b bereits ausgeführt habenrowser.

Wie bei jedem anderen Programm, das Flags akzeptiert, können wir sie verwenden, um das gewünschte Verhalten zu erzeugen.

import subprocess

subprocess.run(['brave', '--incognito'])

Um zusammenzufassen

Ein Unter-process ist ein Computer process CREated von einem anderen process. Wir können das überprüfen processEs läuft auf unserem Computer mit Tools wie htop und dem Task-Manager.

Python verfügt über eine eigene Bibliothek für die Arbeit mit Subprocesses. Derzeit ist die Lauf Funktion gibt uns eine einfache Schnittstelle zu create und Sub verwaltenprocesszB.

Wir können erstellenate jede Art von Anwendung mit ihnen, weil wir direkt mit dem Betriebssystem interagieren.

FinallyDenken Sie daran, dass der beste Weg zum Lernen darin besteht, zu lernen CREate etwas du würdest gerne benutzen.

Teilen:
  • Daniel Diaz
    Autor
    Self unterrichtete Python/Django-Entwickler, lernte und baute immer großartige Dinge. Technisch writer, und Schöpfer von Developer Road.

Danke an unsere Sponsoren

Weitere großartige Lektüre zum Thema Entwicklung

Treiben Sie Ihr Geschäft an

Einige der Tools und Services, die Ihrem Unternehmen helfen grow.