Come eseguire i comandi della shell in Python utilizzando il metodo di esecuzione dei sottoprocessi

How Execute Shell Commands Python Using Subprocess Run Method



Subprocess è un modulo Python integrato che può essere utilizzato per creare nuovi processi e interagire con i loro flussi di dati di input e output. In termini più semplici, puoi usarlo per eseguire comandi di shell ed eseguire binari eseguibili solitamente sparsi in varie cartelle bin su un file system Linux. È inoltre possibile fornire un percorso completo a un binario eseguibile e utilizzare qualsiasi opzione della riga di comando associata al binario. Questo articolo spiegherà come usare il modulo subprocess e il suo metodo di esecuzione nelle app Python. Tutti gli esempi di codice nell'articolo sono testati con Python 3.8.2 su Ubuntu 20.04.

Il metodo Subprocess.run

Il metodo Subprocess.run accetta un elenco di argomenti. Quando il metodo viene chiamato, esegue il comando e attende il completamento del processo, restituendo alla fine un oggetto CompletedProcess. L'oggetto CompletedProcess restituisce stdout, stderr, gli argomenti originali utilizzati durante la chiamata al metodo e un codice restituito. Stdout si riferisce al flusso di dati prodotto dal comando, mentre stderr si riferisce a eventuali errori generati durante l'esecuzione del programma. Qualsiasi codice di ritorno diverso da zero (codice di uscita) significherebbe un errore con il comando eseguito nel metodo subprocess.run.







Esempio 1: contenuto di output di un file di testo utilizzando il metodo Subprocess.run

Il comando seguente restituirà il contenuto di un file data.txt, supponendo che contenga una stringa name=John.



importare sottoprocesso
sottoprocesso.correre(['gatto', 'data.txt'])

L'esecuzione del codice sopra restituirà il seguente output:



nome=John
Processo completato(argomenti=['gatto', 'data.txt'],codice di ritorno=0)

Il primo elemento dell'argomento della lista è il nome del comando da eseguire. Qualsiasi elemento nell'elenco che segue il primo elemento è considerato opzioni o opzioni della riga di comando. È possibile utilizzare anche trattini singoli e doppi per definire le opzioni. Ad esempio, per elencare file e cartelle in una directory, il codice sarebbe subprocess.run([ls, -l]. Nella maggior parte di questi casi, puoi considerare qualsiasi argomento separato da spazi in un comando di shell come un singolo elemento in l'elenco fornito al metodo subprocess.run.





Esempio 2: sopprimere l'output del metodo Subprocess.run

Per eliminare l'output del metodo subprocess.run, sarà necessario fornire stdout=subprocess.DEVNULL e stderr=subprocess.DEVNULL come argomenti aggiuntivi.

importare sottoprocesso

sottoprocesso.correre(['gatto', 'data.txt'],stdout=sottoprocesso.DEVNULL,
stderr=sottoprocesso.DEVNULL)

L'esecuzione del codice sopra produrrà il seguente output:



CompletedProcess(args=['cat', 'data.txt'], returncode=0)

Esempio 3: Cattura l'output del metodo Subprocess.run

Per acquisire l'output del metodo subprocess.run, utilizzare un argomento aggiuntivo denominato capture_output=True.

importare sottoprocesso
produzione= sottoprocesso.correre(['gatto', 'data.txt'],cattura_output=Vero)
Stampa (produzione)

L'esecuzione del codice sopra produrrà il seguente output:

Processo completato(argomenti=['gatto', 'data.txt'],codice di ritorno=0,
stdout=B'nome=Giovanni ',stderr=B'')

È possibile accedere individualmente ai valori stdout e stderr utilizzando i metodi output.stdout e output.stderr. L'output viene prodotto come una sequenza di byte. Per ottenere una stringa come output, utilizzare il metodo output.stdout.decode(utf-8). Puoi anche fornire text=True come argomento extra alla chiamata subprocess.run per ottenere l'output in formato stringa. Per ottenere il codice di stato di uscita, puoi utilizzare il metodo output.returncode.

Esempio 4: sollevare l'eccezione in caso di errore del comando eseguito dal metodo Subprocess.run

Per sollevare un'eccezione quando il comando termina con uno stato diverso da zero, utilizzare l'argomento check=True.

importare sottoprocesso
sottoprocesso.correre(['gatto', 'data.tx'],cattura_output=Vero,testo=Vero,dai un'occhiata=Vero)

L'esecuzione del codice sopra produrrà il seguente output:

sollevare CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Comando '['cat', 'data.tx']'
ha restituito uno stato di uscita diverso da zero 1.

Esempio 5: passare una stringa al comando eseguito dal metodo Subprocess.run

È possibile passare una stringa al comando da eseguire dal metodo subprocess.run utilizzando l'argomento input='stringa'.

importare sottoprocesso
produzione= sottoprocesso.correre(['gatto'], ingresso='data.txt',cattura_output=Vero,
testo=Vero,dai un'occhiata=Vero)
Stampa (produzione)

L'esecuzione del codice sopra produrrà il seguente output:

CompletedProcess(args=['cat'], returncode=0, stdout='data.txt', stderr='')

Come puoi vedere, il codice sopra passa data.txt come stringa e non come oggetto file. Per passare data.txt come file, usa l'argomento stdin.

insieme a aprire('data.txt') comeF:
produzione= sottoprocesso.correre(['gatto'],standard=F,cattura_output=Vero,
testo=Vero,dai un'occhiata=Vero)
Stampa (produzione)

L'esecuzione del codice sopra produrrà il seguente output:

CompletedProcess(args=['cat'], returncode=0, stdout='name=John ', stderr='')

Esempio 6: eseguire il comando direttamente nella shell utilizzando il metodo Subprocess.run

È possibile eseguire un comando direttamente in una shell così com'è, invece di utilizzare una stringa divisa nel comando principale e nelle opzioni che lo seguono. Per fare ciò, devi passare shell=True come argomento aggiuntivo. Questo è tuttavia scoraggiato dagli sviluppatori Python poiché l'uso di shell=True può portare a problemi di sicurezza. Puoi leggere di più sulle implicazioni per la sicurezza da qui .

importare sottoprocesso
sottoprocesso.correre('gatto 'data.txt'',guscio=Vero)

L'esecuzione del codice sopra produrrà il seguente output:

nome=Giovanni

Conclusione

Il metodo subprocess.run in Python è piuttosto potente, in quanto consente di eseguire comandi di shell all'interno di Python stesso. Questo aiuta a limitare tutto il codice a python stesso senza la necessità di avere codice di script della shell aggiuntivo in file separati. Tuttavia, può essere piuttosto complicato tokenizzare correttamente i comandi della shell in un elenco python. Puoi usare il metodo shlex.split() per tokenizzare semplici comandi di shell, ma in comandi lunghi e complessi, specialmente quelli con simboli pipe, shlex non riesce a dividere correttamente il comando. In questi casi, il debug può essere un problema complicato. È possibile utilizzare l'argomento shell=True per evitare ciò, ma ci sono alcuni problemi di sicurezza associati a questa azione.