2 days ago

Shell-Befehle aus Python aufrufen



Es gibt ein paar Möglichkeiten, um aus Python Shell-Befehle aufzurufen, doch nur zwei sind relevant. Sie unterscheiden sich durch ihre Synchronität.

Mit der Programmiersprache Python kann man fast alles machen; muss man aber nicht. Häufig ist es einfacher und effizienter, bestehende Programme aufzurufen, statt dieselbe Funktionalität in Python nachzubauen. Das gilt insbesondere für Aufgaben, die man mit einem Befehl auf der Kommandozeile erledigen kann.

Nun gibt es in Python mehrere Möglichkeiten, Shell-Befehle aufzurufen, als da wären: os.system oder os.popen. Vergesst diese Befehle; ihr braucht nur einen, nämlich: subprocess.run. Um diesen Befehl verwenden zu können, müsst ihr zuerst das Modul subprocess importieren: import subprocess. Dann könnt ihr ein Shell-Kommando aufrufen, z. B.:

import subprocess subprocess.run(["echo", "Linux ist cool"])

Wie ihr seht, wird das Shell-Kommando als Liste übergeben: ['a', 'b', 'c']. Das ist notwendig, wenn man einem Befehl Parameter übergeben möchte, wie es im obigen Beispiel der Fall ist. Manchmal kann auch nur einen String übergeben, wie ihr im nächsten Beispiel sehen werdet. Fragt mich nicht, wann es ohne Liste funktioniert; im Zweifel nehmt ihr immer eine Liste.

Tatsächlich ist subprocess.run nur ein Wrapper um subprocess.Popen. Ersterer arbeitet im synchronen Modus, das heisst, dass das Python-Skript erst fortfährt, wenn der Befehl fertig ist. Dieses Verhalten ist nicht immer sinnvoll. Stellt euch vor, ihr möchtet ein Musikstück abspielen und währenddessen Befehle zur Steuerung entgegennehmen. Das geht mit subprocess.run nicht, weil das Python-Skript so lange wartet, bis die Musikwiedergabe endet.

In diesem Fall braucht man einen asynchronen Modus, bei dem nicht auf das Ende des Befehls gewartet wird. Und hier kommt subprocess.Popen ins Spiel. Damit ihr euch das besser vorstellen könnt, habe ich ein kleine Python-Skript geschrieben:

#!/usr/bin/env python3 import subprocess command = 'mpv https://samplelib.com/lib/preview/mp3/sample-3s.mp3' p = subprocess.Popen(command, shell=True) p.wait() print('\n1. Es wurde gewartet, bis der Prozess endete.\n') p = subprocess.Popen(command, shell=True) print('\n2. Es wurde nicht auf das Ende des Prozesses gewartet.\n') subprocess.run(command, shell=True) print('\n3. Es wurde gewartet, bis der Prozess endete.\n')

Ihr könnt das Skript z. B. als 'test.py' abspeichern und mit 'python test.py' laufen lassen. Voraussetzung ist, das der Medien-Player mpv bei euch installiert ist. Was macht das Skript? Nach dem Shebang in der ersten Zeile, wird das Modul subprocess importiert. Dann kommt das Shell-Kommando in der Variable command. Das Kommando könnt ihr zuerst im Terminal ausprobieren. Es spielt eine (grässliche) 3-Sekunden MP3-Datei mit mpv ab.

Nun folgen drei verschiedene Aufrufe des Kommandos. Beim Ersten wird das Kommando asynchron mit Popen gestartet. Mit p.wait warten wir auf das Ende des Subprozesses. Wenn die Musik fertig ist, erfolgt die print-Ausgabe. Das Zweite macht dasselbe wie das Erste, allerdings ohne auf das Prozessende zu warten. Die print-Ausgabe erfolgt noch, während die Musik spielt. Beim Dritten wird das synchrone run verwendet. Daher erscheint die print-Ausgabe erst nach dem Ende der Musik.

Beide Befehle kennen eine Vielzahl von weiteren Argumenten und begleitenden Befehlen aus dem Subprocess-Modul. Deren Erläuterung würde das Ziel und den Umfang dieses Artikels sprengen. Wer mehr darüber wissen möchte, wird in der Quelle fündig.

Titelbild: https://pixabay.com/vectors/bash-command-line-linux-shell-148836/ und Stable Diffusion 'Snake'

Quelle: https://docs.python.org/3/library/subprocess.html


GNU/Linux.ch ist ein Community-Projekt. Bei uns kannst du nicht nur mitlesen, sondern auch selbst aktiv werden. Wir freuen uns, wenn du mit uns über die Artikel in unseren Chat-Gruppen oder im Fediverse diskutierst. Auch du selbst kannst Autor werden. Reiche uns deinen Artikelvorschlag über das Formular auf unserer Webseite ein.
Gesamten Artikel lesen

© Varient 2025. All rights are reserved