Com executar ordres de shell a Python mitjançant el mètode d'execució de subprocessos

How Execute Shell Commands Python Using Subprocess Run Method



Subprocess és un mòdul Python integrat que es pot utilitzar per crear processos nous i interactuar amb els seus fluxos de dades d’entrada i sortida. En termes més senzills, podeu utilitzar-lo per executar ordres de l'intèrpret d'ordres i executar binaris executables generalment dispersos en diverses carpetes de bin a través d'un sistema de fitxers Linux. També podeu proporcionar un camí d'accés complet a un binari executable i utilitzar qualsevol commutador de línia d'ordres associat al binari. En aquest article s’explicarà com utilitzar el mòdul de subprocés i el seu mètode d’execució a les aplicacions de Python. Tots els exemples de codi de l'article es proven amb Python 3.8.2 a Ubuntu 20.04.

El mètode Subprocess.run

El mètode Subprocess.run pren una llista d'arguments. Quan es crida el mètode, executa l'ordre i espera que finalitzi el procés, retornant un objecte CompletedProcess al final. L'objecte CompletedProcess retorna stdout, stderr, arguments originals utilitzats mentre es crida al mètode i un codi de retorn. Stdout es refereix al flux de dades produït per l'ordre, mentre que stderr es refereix a qualsevol error generat durant l'execució del programa. Qualsevol codi de retorn diferent de zero (codi de sortida) significaria un error amb l'ordre executada al mètode subprocess.run.







Exemple 1: Contingut de sortida d'un fitxer de text mitjançant el mètode Subprocess.run

L'ordre següent mostrarà el contingut d'un fitxer data.txt, suposant que conté una cadena name = John.



importació subprocés
subprocés.correr(['gat', 'data.txt'])

Executant el codi anterior es retornarà la següent sortida:



nom=Joan
CompletedProcess(args=['gat', 'data.txt'],codi de retorn=0)

El primer element de l'argument de llista és el nom de l'ordre que s'ha d'executar. Qualsevol element de la llista que segueix el primer element es considera opcions o commutadors de línia d'ordres. També podeu utilitzar guions simples i dobles per definir les opcions. Per exemple, per llistar fitxers i carpetes d'un directori, el codi seria subprocess.run ([ls, -l]. En la majoria d'aquests casos, podeu considerar qualsevol argument separat en un ordre de l'intèrpret d'ordres com un element individual a la llista subministrada al mètode subprocess.run.





Exemple 2: suprimiu la sortida del mètode Subprocess.run

Per suprimir la sortida del mètode subprocess.run, haureu de proporcionar stdout = subprocess.DEVNULL i stderr = subprocess.DEVNULL com a arguments addicionals.

importació subprocés

subprocés.correr(['gat', 'data.txt'],stdout=subprocés.DEVNULL,
stderr=subprocés.DEVNULL)

Executant el codi anterior es produirà la següent sortida:



Procés completat (args = ['cat', 'data.txt'], returncode = 0)

Exemple 3: Captura la sortida del mètode Subprocess.run

Per capturar la sortida del mètode subprocess.run, utilitzeu un argument addicional anomenat capture_output = True.

importació subprocés
sortida= subprocés.correr(['gat', 'data.txt'],sortida_captura=És cert)
imprimir (sortida)

Executant el codi anterior es produirà la següent sortida:

CompletedProcess(args=['gat', 'data.txt'],codi de retorn=0,
stdout=b'nom = Joan n',stderr=b'')

Podeu accedir individualment als valors stdout i stderr mitjançant els mètodes output.stdout i output.stderr. La sortida es produeix com una seqüència de bytes. Per obtenir una cadena com a sortida, utilitzeu el mètode output.stdout.decode (utf-8). També podeu proporcionar text = True com a argument addicional a la trucada subprocess.run per obtenir la sortida en format de cadena. Per obtenir el codi d'estat de sortida, podeu utilitzar el mètode output.returncode.

Exemple 4: Augmentar l'excepció en cas d'error de l'ordre executat pel mètode Subprocess.run

Per generar una excepció quan l'ordre surti amb un estat diferent de zero, utilitzeu l'argument check = True.

importació subprocés
subprocés.correr(['gat', 'data.tx'],sortida_captura=És cert,text=És cert,comprovar=És cert)

Executant el codi anterior es produirà la següent sortida:

augmentar CalledProcessError (retcode, process.args,
subprocess.CalledProcessError: Ordre '[' cat ',' data.tx ']'
ha retornat l'estat de sortida no zero 1.

Exemple 5: Passar una cadena a l'ordre executada pel mètode Subprocess.run

Podeu passar una cadena a l'ordre que s'executarà mitjançant el mètode subprocess.run mitjançant l'argument input = 'string'.

importació subprocés
sortida= subprocés.correr(['gat'], entrada='data.txt',sortida_captura=És cert,
text=És cert,comprovar=És cert)
imprimir (sortida)

Executant el codi anterior es produirà la següent sortida:

Procés completat (args = ['cat'], returncode = 0, stdout = 'data.txt', stderr = '')

Com podeu veure, el codi anterior passa data.txt com una cadena i no com un objecte de fitxer. Per passar data.txt com a fitxer, utilitzeu l'argument stdin.

amb obert('data.txt') comf:
sortida= subprocés.correr(['gat'],stdin=f,sortida_captura=És cert,
text=És cert,comprovar=És cert)
imprimir (sortida)

Executant el codi anterior es produirà la següent sortida:

Procés completat (args = ['cat'], returncode = 0, stdout = 'name = John n', stderr = '')

Exemple 6: executeu l'ordre directament a l'intèrpret d'ordres mitjançant el mètode Subprocess.run

És possible executar una ordre directament en un intèrpret d'ordres tal qual, en lloc d'utilitzar una divisió de cadenes a l'ordre principal i les opcions que la segueixen. Per fer-ho, heu de passar shell = True com a argument addicional. Tanmateix, això és desaconsellat pels desenvolupadors de python ja que utilitzar shell = True pot provocar problemes de seguretat. Podeu obtenir més informació sobre les implicacions de la seguretat des de aquí .

importació subprocés
subprocés.correr('cat' data.txt '',petxina=És cert)

Executant el codi anterior es produirà la següent sortida:

nom = Joan

Conclusió

El mètode subprocess.run a Python és força potent, ja que us permet executar ordres de shell dins del propi python. Això ajuda a limitar tot el codi al propi python sense la necessitat de tenir codi addicional de script de shell en fitxers separats. No obstant això, pot ser bastant complicat tokenitzar correctament les ordres de l'intèrpret d'ordres en una llista de python. Podeu utilitzar el mètode shlex.split () per simbolitzar ordres senzilles de l'intèrpret d'ordres, però en ordres complexes i llargues, especialment aquelles amb símbols de canonada, shlex no pot dividir correctament l'ordre. En aquests casos, la depuració pot ser un problema complicat. Podeu utilitzar l'argument shell = True per evitar-ho, però hi ha certes preocupacions de seguretat associades a aquesta acció.