Cum se execută comenzi Shell în Python folosind metoda Run Subprocess

How Execute Shell Commands Python Using Subprocess Run Method



Subprocesul este un modul Python încorporat care poate fi utilizat pentru a crea noi procese și a interacționa cu fluxurile lor de date de intrare și ieșire. În termeni mai simpli, îl puteți utiliza pentru a rula comenzi de tip shell și a rula binarele executabile, de obicei împrăștiate în diferite foldere de pe un sistem de fișiere Linux. De asemenea, puteți furniza o cale completă către un binar executabil și puteți utiliza orice comutatoare de linie de comandă asociate binarului. Acest articol va explica cum să utilizați modulul de subproces și metoda de rulare a acestuia în aplicațiile Python. Toate mostrele de cod din articol sunt testate cu Python 3.8.2 pe Ubuntu 20.04.

Metoda Subprocess.run

Metoda Subprocess.run ia o listă de argumente. Când se apelează metoda, execută comanda și așteaptă finalizarea procesului, returnând la final un obiect CompletedProcess. Obiectul CompletedProcess returnează stdout, stderr, argumentele originale utilizate în timpul apelării metodei și un cod de returnare. Stdout se referă la fluxul de date produs de comandă, în timp ce stderr se referă la orice erori ridicate în timpul executării programului. Orice cod de returnare diferit de zero (cod de ieșire) ar însemna eroare la comanda executată în metoda subprocess.run.





Exemplul 1: Conținutul rezultatului unui fișier text utilizând metoda Subprocess.run

Comanda de mai jos va afișa conținutul unui fișier data.txt, presupunând că acesta conține un nume = șir John.



import subproces
subproces.alerga(['pisică', „data.txt”])

Rularea codului de mai sus va reveni la următoarea ieșire:



Nume=Ioan
Proces finalizat(argumente=['pisică', „data.txt”],returncode=0)

Primul element al argumentului listă este numele comenzii de executat. Orice element din listă care urmează primului element sunt considerate opțiuni sau comutatoare din linia de comandă. Puteți utiliza și liniuțe simple și duble, pentru a defini opțiunile. De exemplu, pentru a lista fișiere și foldere într-un director, codul ar fi subprocess.run ([ls, -l]. În majoritatea acestor cazuri, puteți considera orice argument separat de spațiu dintr-o comandă shell ca un element individual în lista furnizată metodei subprocess.run.





Exemplul 2: Suprimați ieșirea metodei Subprocess.run

Pentru a suprima ieșirea metodei subprocess.run, va trebui să furnizați stdout = subprocess.DEVNULL și stderr = subprocess.DEVNULL ca argumente suplimentare.

import subproces

subproces.alerga(['pisică', „data.txt”],stdout=subproces.DEVNULL,
stderr=subproces.DEVNULL)

Rularea codului de mai sus va produce următoarea ieșire:



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

Exemplul 3: Captarea ieșirii metodei Subprocess.run

Pentru a captura ieșirea metodei subprocess.run, utilizați un argument suplimentar numit capture_output = True.

import subproces
ieșire= subproces.alerga(['pisică', „data.txt”],capture_output=Adevărat)
imprimare (ieșire)

Rularea codului de mai sus va produce următoarea ieșire:

Proces finalizat(argumente=['pisică', „data.txt”],returncode=0,
stdout=b'nume = John n',stderr=b'')

Puteți accesa individual valorile stdout și stderr utilizând metodele output.stdout și output.stderr. Ieșirea este produsă ca o secvență de octeți. Pentru a obține un șir ca ieșire, utilizați metoda output.stdout.decode (utf-8). De asemenea, puteți furniza text = True ca un argument suplimentar apelului subprocess.run pentru a obține ieșirea în format șir. Pentru a obține codul de stare de ieșire, puteți utiliza metoda output.returncode.

Exemplul 4: Creșteți excepția la eșecul comenzii executate prin metoda Subprocess.run

Pentru a ridica o excepție când comanda iese cu o stare diferită de zero, utilizați argumentul check = True.

import subproces
subproces.alerga(['pisică', „data.tx”],capture_output=Adevărat,text=Adevărat,Verifica=Adevărat)

Rularea codului de mai sus va produce următoarea ieșire:

ridicați CalledProcessError (retcode, process.args,
subprocess.CalledProcessError: Comanda '[' cat ',' data.tx ']'
a returnat starea de ieșire diferită de zero 1.

Exemplul 5: Treceți un șir la comandă executat prin metoda Subprocess.run

Puteți trece un șir la comanda care urmează să fie executată prin metoda subprocess.run utilizând argumentul input = 'string'.

import subproces
ieșire= subproces.alerga(['pisică'], intrare=„data.txt”,capture_output=Adevărat,
text=Adevărat,Verifica=Adevărat)
imprimare (ieșire)

Rularea codului de mai sus va produce următoarea ieșire:

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

După cum puteți vedea, codul de mai sus transmite data.txt ca șir și nu ca obiect de fișier. Pentru a transmite data.txt ca fișier, utilizați argumentul stdin.

cu deschis(„data.txt”) la fel def:
ieșire= subproces.alerga(['pisică'],stdin=f,capture_output=Adevărat,
text=Adevărat,Verifica=Adevărat)
imprimare (ieșire)

Rularea codului de mai sus va produce următoarea ieșire:

Proces finalizat (args = ['cat'], returncode = 0, stdout = 'name = John n', stderr = '')

Exemplul 6: Executați comanda direct în Shell folosind metoda Subprocess.run

Este posibil să rulați o comandă direct într-un shell așa cum este, în loc să utilizați un șir divizat în comanda principală și opțiunile care o urmează. Pentru a face acest lucru, trebuie să treceți shell = True ca argument suplimentar. Cu toate acestea, acest lucru este descurajat de dezvoltatorii python, deoarece utilizarea shell = True poate duce la probleme de securitate. Puteți citi mai multe despre implicațiile de securitate din Aici .

import subproces
subproces.alerga(„pisică” data.txt ””,coajă=Adevărat)

Rularea codului de mai sus va produce următoarea ieșire:

nume = John

Concluzie

Metoda subprocess.run din Python este destul de puternică, deoarece vă permite să rulați comenzi shell în propriul python. Acest lucru ajută la limitarea întregului cod la python în sine, fără a fi nevoie să aveți cod de script shell suplimentar în fișiere separate. Cu toate acestea, poate fi destul de dificil să tokenizeze corect comenzile shell dintr-o listă python. Puteți utiliza metoda shlex.split () pentru a simboliza comenzile simple ale shell-ului, dar în comenzile lungi și complexe - în special cele cu simboluri pipe - shlex nu reușește să împartă corect comanda. În astfel de cazuri, depanarea poate fi o problemă dificilă. Puteți utiliza argumentul shell = True pentru a evita acest lucru, dar există anumite probleme de securitate asociate acestei acțiuni.