come eseguire un comando bash in uno script python


Risposte:


16

La risposta di @milne funziona, ma subprocess.call()ti dà pochi feedback.

Preferisco usare in subprocess.check_output()modo da poter analizzare ciò che è stato stampato su stdout:

 import subprocess
 res = subprocess.check_output(["sudo", "apt", "update"])
 for line in res.splitlines():
     # process the output line by line

check_output genera un errore all'uscita zero del comando invocato

Si noti che questo non invoca basho un'altra shell se non si specifica l' shellargomento della parola chiave per la funzione (lo stesso vale per subprocess.call(), e non si dovrebbe se non necessario in quanto impone un rischio per la sicurezza), invoca direttamente il comando.

Se ti ritrovi a fare molte (diverse) invocazioni di comandi da Python, potresti voler guardare al plumbum . Con ciò puoi fare (IMO) più leggibile:

from plumbum.cmd import sudo, apt, echo, cut

res = sudo[apt["update"]]()
chain = echo["hello"] | cut["-c", "2-"]
chain()

Si consiglia di utilizzare ( os.popeno os.system), ad esempio res = os.popen('sudo apt update').read():? @Anthon
Alper

1
@alper Leggi 0324 python.org/dev/peps/pep-0324 . Questo spiega il razionale per fare subprocess, anche se os.systeme os.popengià esisteva. Tali PEP non sono banali per essere accettati. Diverse persone ci hanno pensato molto più di quanto tu o io mai faremo. E subprocessè migliorato dal 2003, gli altri sono ancora lì per compatibilità con le versioni precedenti. Hai rosso la os.systempagina del manuale: il modulo di sottoprocesso fornisce strutture più potenti per generare nuovi processi e recuperare i loro risultati; usare quel modulo è preferibile usare questa funzione.
Anthon,

1
@alper Sì, potresti. Come ho indicato, ciò rappresenta un potenziale rischio per la sicurezza, quindi non so perché pensi che sia raccomandato. E invocare lo sudorenderà solo più grave. Forse usare python-apt è una soluzione migliore (non l'ho analizzato da solo).
Anthon,

1
@per in tal caso dare un'occhiata seria al piombo , vale la pena mettersi al passo con quello.
Anthon,

1
@alper Se sei su Python3 devi farlo, su Python2 non lo fai. Si prega di non utilizzare i commenti qui come sistema di chat. Se hai una domanda, pubblicala come tale.
Anthon,

8

È possibile usare bash come programma, con il parametro -c per eseguire i comandi:

Esempio:

bashCommand = "sudo apt update"
output = subprocess.check_output(['bash','-c', bashCommand])

7

Il modulo di sottoprocesso è progettato per fare questo:

import subprocess
subprocess.call(["sudo", "apt", "update"])

Se desideri che lo script venga interrotto se il comando non riesce, potresti prendere in considerazione l'utilizzo check_call()invece di analizzare tu stesso il codice di ritorno:

subprocess.check_call(["sudo", "apt", "update"])

questo mi ha dato il seguente traceback: Traceback (most recent call last): File "/home/Dremor/test.py", line 3, in <module> subprocess.call('sudo', 'yum', 'update') File "/usr/lib64/python3.4/subprocess.py", line 537, in call with Popen(*popenargs, **kwargs) as p: File "/usr/lib64/python3.4/subprocess.py", line 767, in __init__ raise TypeError("bufsize must be an integer") TypeError: bufsize must be an integer (sto usando yum come sto usando Fedora come sistema operativo principale)
Dremor

3
Hai dimenticato le parentesi quadre
Milind Dumbare,

1
Nota anche che subprocess.call()sta bloccando mentre subprocess.Popen()non sta bloccando ...
heemayl

Cosa intendi con "blocco"? @heemayl
Alper

2

Inoltre puoi usare 'os.popen'.

Esempio:

import os

command = os.popen('ls -al')
print(command.read())
print(command.close())

Produzione:

total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root   77 ago 13 21:53 test.py

None

0

usa il modulo sottoprocesso

import subprocess
command = 'sudo apt update'
subprocess.check_call(command.split())

perché
ricevo

subprocess.check_call (["sudo", "apt", "update"])
aquagremlin

CalledProcessError Traceback (ultima chiamata più recente) <ipython-input-21-33ce645708e7> in <module> () ----> 1 subprocess.check_call (["sudo", "apt", "update"]) / usr / lib / python2.7 / subprocess.pyc in check_call (* popenargs, ** kwargs) 188 se cmd è None: 189 cmd = popenargs [0] -> 190 raise CalledProcessError (retcode, cmd) 191 return 0 192 CalledProcessError: Command '[' sudo ',' apt ',' update ']' ha restituito uno stato di uscita diverso da zero 1
aquagremlin

questo errore si verifica solo quando lo eseguo su un quaderno
jupyter

forse inizierò una nuova domanda dato che è ot
aquagremlin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.