HOWTO · Python

Come eseguire un comando Bash in Python

Questo tutorial mostra come eseguire comandi bash in Python, concentrandosi sui comandi Git. Scopri i metodi migliori, inclusi subprocess e os.system, per eseguire i comandi in modo efficace. Migliora il tuo flusso di lavoro con esempi pratici e spiegazioni chiare. Perfetto per gli sviluppatori che vogliono automatizzare le attività e semplificare i loro processi.

In questa pagina

Python può avviare programmi da riga di comando e comandi shell per attività come la creazione di directory o l’uso di Git. Per i comandi che terminano, subprocess.run() è di solito il miglior punto di partenza: può catturare l’output e gli errori e fornisce un codice di ritorno. Usa os.system() per i casi semplici che non richiedono l’output catturato, e scegli subprocess.Popen() quando devi interagire con un processo mentre è in esecuzione.

Eseguire un comando con subprocess.run()

Passa una sequenza di argomenti per invocare direttamente un eseguibile. In questo modo si evita di chiedere a una shell di analizzare il comando. L’esempio utilizza l’interprete Python in esecuzione, quindi non dipende dall’installazione di Git né da una shell particolare.

import subprocess
import sys

result = subprocess.run(
    [sys.executable, "-c", "print('Hello from Python')"],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
)

print("stdout:", result.stdout)
print("stderr:", result.stderr)
print("return code:", result.returncode)
stdout: b'Hello from Python\n'
stderr: b''
return code: 0

stdout e stderr sono qui dei byte, e returncode è un intero. Un codice di ritorno pari a 0 indica convenzionalmente il successo; un valore diverso da zero segnala che il programma ha riportato un problema. Puoi controllarlo tu stesso oppure passare check=True affinché run() sollevi CalledProcessError in caso di codice di ritorno diverso da zero. Per eseguire Git, ad esempio, passa un elenco di argomenti come ['git', 'status']; il suo output dipende dal repository e deve essere trattato come dati, senza presumere che abbia un contenuto fisso.

L’invocazione di un programma non è automaticamente un comando Bash. La sintassi shell come le pipe, i reindirizzamenti o && richiede una shell. Impostare shell=True chiede a Python di usare la shell della piattaforma; non garantisce Bash. Evita di interpolare input non attendibili in un comando shell perché ciò può consentire l’iniezione di comandi.

Eseguire un comando shell con os.system()

os.system() è un’opzione limitata per un comando semplice quando non devi catturare il suo output né gestire gli errori in dettaglio. Ad esempio, os.system("mkdir reports") chiede alla shell della piattaforma di eseguire il comando di creazione della directory. Il comando scrive nei flussi della console ereditati. La funzione restituisce un valore di stato, non l’output ordinario del comando; l’interpretazione di tale stato può variare a seconda della piattaforma. Preferisci subprocess.run() quando devi ispezionare in modo coerente l’output catturato, gli errori o un codice di ritorno.

Usare subprocess.Popen() per i processi in corso

Usa subprocess.Popen() quando il programma ha bisogno di input o di un’altra interazione prima di terminare. Avvia il processo e fornisce al tuo codice un oggetto processo con cui lavorare. Per un processo con output limitato, imposta stdout=subprocess.PIPE e stderr=subprocess.PIPE, quindi chiama communicate() per leggere tali flussi e attendere il completamento. I valori dei flussi restituiti sono byte, a meno che tu non disponga la decodifica separatamente.

communicate() è utile quando il processo terminerà e il suo output catturato può stare in memoria. Non è un approccio di streaming per un output illimitato. Una volta che communicate() è stato completato, il processo è terminato; non è necessario chiamare kill() o terminate() su di esso. Per i comandi ordinari che semplicemente terminano, run() fornisce l’interfaccia più semplice.

Scegliere il metodo giusto

Usa subprocess.run() per la maggior parte dei comandi: passa un elenco di argomenti, cattura i flussi quando necessario e ispeziona returncode. Usa os.system() solo quando è sufficiente un breve comando shell e il suo output e il suo stato dettagliato non sono importanti. Usa Popen() quando il tuo programma deve gestire un processo in esecuzione o scambiare dati con esso. Scegli una shell solo quando il comando richiede la sintassi shell, e tieni i valori non attendibili fuori dalle stringhe shell interpolate.