Come eseguire gli script bash usando Python?

Se stai usando Linux, allora adorerai sicuramente i comandi della shell.

E se stai lavorando con Python, potresti aver provato ad automatizzare le cose. Questo è un modo per risparmiare tempo. Potresti anche avere alcuni script bash per automatizzare le cose.

Python è utile per scrivere script rispetto a bash. E la gestione degli script Python è facile rispetto agli script bash. Troverai difficile mantenere gli script bash una volta che sta crescendo.

Ma cosa succede se si dispone già di script bash che si desidera eseguire utilizzando Python?

C’è un modo per eseguire i comandi e gli script bash in Python?

Sì, Python ha un modulo integrato chiamato subprocess che viene utilizzato per eseguire i comandi e gli script all’interno degli script Python. Vediamo in dettaglio come eseguire comandi e script bash negli script Python.

Esecuzione dei comandi Bash

Come avrai già visto, il sottoprocesso del modulo viene utilizzato per eseguire i comandi e gli script bash. Fornisce diversi metodi e classi per lo stesso.

Ci sono principalmente un metodo e una classe da conoscere dal modulo del sottoprocesso. Sono correre e Popen. Questi due ci aiutano a eseguire i comandi bash negli script Python. Vediamoli uno per uno.

subprocess.run()

Il metodo subprocess.run() prenderà un elenco di stringhe come argomento posizionale. Questo è obbligatorio in quanto ha il comando bash e gli argomenti per esso. Il primo elemento nell’elenco è il nome del comando e gli elementi rimanenti sono gli argomenti del comando.

Vediamo un rapido esempio.

import subprocess
subprocess.run(["ls"])

Lo script sopra elenca tutti gli elementi nella directory di lavoro corrente mentre lo script si trova. Non ci sono argomenti per il comando nello script precedente. Abbiamo dato solo il comando bash. Possiamo fornire argomenti aggiuntivi al comando ls come -l, -a, -la, ecc.

Vediamo un rapido esempio con argomenti di comando.

import subprocess
subprocess.run(["ls", "-la"])

Il comando precedente mostra tutti i file inclusi i file nascosti insieme alle autorizzazioni. Abbiamo fornito l’argomento la che mostra informazioni aggiuntive su file e directory e file nascosti.

Potremmo finire per fare degli errori durante la scrittura dei comandi. Gli errori aumenteranno in base agli errori. E se volessi catturarli e usarli in seguito? Sì, possiamo farlo usando l’argomento della parola chiave stderr.

Vediamo un esempio.

import subprocess
result = subprocess.run(["cat", "sample.txt"], stderr=subprocess.PIPE, text=True)
print(result.stderr)

Assicurati di non avere il file con il nome sample.txt nella directory di lavoro. Il valore dell’argomento della parola chiave stderr è PIPE che aiuta a restituire l’errore in un oggetto. Possiamo accedervi in ​​seguito con lo stesso nome. E l’argomento della parola chiave text aiuta a dire che l’output dovrebbe essere una stringa.

Allo stesso modo, possiamo acquisire l’output del comando utilizzando l’argomento della parola chiave stdout.

import subprocess
result = subprocess.run(["echo", "Hello, World!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(result.stdout)

subprocess.run() – input

È possibile fornire input ai comandi utilizzando l’argomento della parola chiave input. Daremo input in un formato stringa. Quindi, dobbiamo impostare il testo dell’argomento della parola chiave su True. Per impostazione predefinita, lo prende in byte.

Diamo un’occhiata a un esempio.

import subprocess
subprocess.run(["python3", "add.py"], text=True, input="2 3")

Nel programma sopra, lo script Python add.py prenderà due numeri come input. Abbiamo fornito l’input allo script Python utilizzando l’argomento della parola chiave input.

subprocess.Popen()

La classe subprocess.Popen() è avanzata rispetto al metodo subprocess.run(). Ci offre più opzioni per eseguire i comandi. Creeremo un’istanza di subprocess.Popen() e la useremo per varie cose come conoscere lo stato dell’esecuzione del comando, ottenere output, fornire input, ecc.,

Ci sono diversi metodi della classe subprocess.Popen() che dobbiamo conoscere. Vediamoli uno per uno insieme agli esempi di codice.

aspettare

Viene utilizzato per attendere il completamento dell’esecuzione del comando. Le righe successive dello script Python non verranno eseguite fino al completamento del comando precedente scritto dopo il metodo wait. Vediamo l’esempio.

import subprocess
process = subprocess.Popen(["ls", "-la"])
print("Completed!")

Esegui il codice sopra e osserva l’output. Vedrai che il messaggio Completato! viene stampato prima dell’esecuzione del comando. Possiamo evitarlo usando il metodo wait. Aspettiamo fino al completamento del comando.

import subprocess
process = subprocess.Popen(["ls", "-la"])
process.wait()

print("Completed!")

Se vedi l’output per il codice sopra, ti renderai conto che l’attesa sta effettivamente funzionando. L’istruzione print viene eseguita dopo il completamento dell’esecuzione del comando.

comunicare

Il metodo di comunicazione viene utilizzato per ottenere l’output, l’errore e fornire l’input al comando. Restituisce una tupla contenente rispettivamente output ed errore. Vediamo un esempio.

import subprocess
process = subprocess.Popen(["echo", "Hello, World!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
result = process.communicate()
print(result)

subprocess.Popen() – input

Non possiamo passare direttamente l’input alla classe Popen. Dobbiamo usare l’argomento della parola chiave chiamato stdin per dare l’input al comando. L’istanza della classe Popen ci fornirà l’oggetto stdin. Ha un metodo chiamato write che viene utilizzato per dare l’input al comando.

Come discusso in precedenza, per impostazione predefinita prenderà input come oggetti simili a byte. Quindi, non dimenticare di impostare il testo dell’argomento della parola chiave su True durante la creazione dell’istanza di Popen.

Vediamo un esempio.

import subprocess
process = subprocess.Popen(["python3", "add.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
process.stdin.write("2 3")
process.stdin.close()
print(process.stdout.read())

sondaggio

Il metodo poll viene utilizzato per verificare se l’esecuzione del comando è stata completata o meno. Questo metodo restituirà None se il comando è ancora in esecuzione. Vediamo un esempio.

import subprocess
process = subprocess.Popen(['ping', '-c 5', 'geekflare.com'], stdout=subprocess.PIPE, text=True)
while True:
    output = process.stdout.readline()
    if output:
    	print(output.strip())
    result = process.poll()
    if result is not None:
        break

Nel codice sopra, abbiamo utilizzato il comando ping con 5 richieste. C’è un ciclo infinito che itera fino al completamento dell’esecuzione del comando. Abbiamo utilizzato il metodo poll per verificare lo stato di esecuzione del comando. Se il metodo poll restituisce un codice diverso da None, l’esecuzione viene completata. E il ciclo infinito si interrompe.

Esecuzione di script Bash

Abbiamo visto due modi per eseguire i comandi. Ora vediamo come eseguire gli script bash negli script Python.

Il sottoprocesso ha un metodo chiamato call. Questo metodo viene utilizzato per eseguire gli script bash. Il metodo restituisce il codice di uscita dallo script bash. Il codice di uscita predefinito per gli script bash è 0. Vediamo un esempio.

Crea uno script bash con il nome practice.sh come segue.

#!/bin/bash

echo "Hello, World!"
exit 1

Ora, scrivi uno script Python, esegui lo script bash sopra.

import subprocess
exit_code = subprocess.call('./practice.sh')
print(exit_code)

Otterrai il seguente output una volta eseguito lo script Python sopra.

Hello, World!
1

Conclusione

Abbiamo visto come eseguire comandi e script bash in Python. Puoi usarli per automatizzare le cose in modo più efficiente.

Buona codifica 👨‍💻