Kako izvesti ukaze lupine v Pythonu z uporabo metode podprocesa

How Execute Shell Commands Python Using Subprocess Run Method



Podproces je vgrajen modul Python, ki ga lahko uporabite za ustvarjanje novih procesov in interakcijo z njihovimi vhodnimi in izhodnimi podatkovnimi tokovi. Preprosteje povedano, ga lahko uporabite za izvajanje ukazov lupine in izvajanje izvedljivih binarnih datotek, ki so običajno razpršene v različnih mapah za bin po datotečnem sistemu Linux. Do izvedljive binarne datoteke lahko vnesete tudi celotno pot in uporabite vsa stikala ukazne vrstice, povezana z binarno datoteko. Ta članek bo razložil, kako uporabljati podprocesni modul in njegovo metodo izvajanja v aplikacijah Python. Vsi vzorci kod v članku so preizkušeni s Pythonom 3.8.2 v Ubuntu 20.04.

Metoda Subprocess.run

Metoda Subprocess.run sprejme seznam argumentov. Ko se metoda pokliče, izvede ukaz in počaka, da se postopek konča, ter na koncu vrne objekt CompletedProcess. Objekt CompletedProcess vrne stdout, stderr, izvirne argumente, uporabljene pri klicanju metode, in vrnjeno kodo. Stdout se nanaša na podatkovni tok, ki ga ustvari ukaz, medtem ko se stderr nanaša na vse napake, ki se pojavijo med izvajanjem programa. Vsaka povratna koda brez izida (izhodna koda) bi pomenila napako pri ukazu, izvedenem v metodi subprocess.run.







Primer 1: Izhodna vsebina besedilne datoteke z uporabo metode Subprocess.run

Spodnji ukaz bo prikazal vsebino datoteke data.txt, ob predpostavki, da vsebuje ime = niz John.



uvoz podproces
podproces.teči(['mačka', 'data.txt'])

Zagon zgornje kode bo vrnil naslednji izhod:



ime=Janez
Dokončan proces(args=['mačka', 'data.txt'],povratna koda=0)

Prvi element argumenta list je ime ukaza, ki ga je treba izvesti. Vsak element na seznamu, ki sledi prvemu elementu, velja za možnosti ali stikala ukazne vrstice. Za določitev možnosti lahko uporabite tudi enojne in dvojne pomišljaje. Če želite na primer prikazati datoteke in mape v imeniku, bi bila koda podproces.run ([ls, -l]. V večini teh primerov lahko kateri koli argument, ločen s presledkom v ukazu lupine, upoštevate kot posamezen element v seznam, podan metodi subprocess.run.





Primer 2: Zatiranje izhoda metode Subprocess.run

Če želite potlačiti izhod metode subprocess.run, boste morali kot dodatne argumente vnesti stdout = subprocess.DEVNULL in stderr = subprocess.DEVNULL.

uvoz podproces

podproces.teči(['mačka', 'data.txt'],stdout=podproces.DEVNULL,
stderr=podproces.DEVNULL)

Izvajanje zgornje kode bo ustvarilo naslednje rezultate:



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

Primer 3: Zajemite izhod metode Subprocess.run

Če želite zajeti rezultat metode subprocess.run, uporabite dodaten argument z imenom capture_output = True.

uvoz podproces
izhod= podproces.teči(['mačka', 'data.txt'],zajem_izhod=Prav)
tiskanje (izhod)

Izvajanje zgornje kode bo ustvarilo naslednje rezultate:

Dokončan proces(args=['mačka', 'data.txt'],povratna koda=0,
stdout=b'ime = Janez n',stderr=b'')

Do vrednosti stdout in stderr lahko dostopate posamično z uporabo metod output.stdout in output.stderr. Izhod je izdelan kot zaporedje bajtov. Če želite niz dobiti kot izhod, uporabite metodo output.stdout.decode (utf-8). Besedilo = True lahko vnesete tudi kot dodaten argument klicu subprocess.run, da dobite izpis v nizu. Kodo stanja izhoda dobite z metodo output.returncode.

Primer 4: dvignite izjemo pri neuspešnem ukazu, izvedenem po metodi Subprocess.run

Če želite izločiti izjemo, ko ukaz izstopi s statusom, ki ni nič, uporabite argument check = True.

uvoz podproces
podproces.teči(['mačka', 'data.tx'],zajem_izhod=Prav,besedilo=Prav,preveri=Prav)

Izvajanje zgornje kode bo ustvarilo naslednje rezultate:

dvignite CalledProcessError (retcode, process.args,
subprocess.CalledProcessError: Ukaz '[' cat ',' data.tx ']'
vrnilo stanje izhoda brez nič 1.

Primer 5: posredujte niz ukazu, izvedenemu po metodi Subprocess.run

Ukaz lahko posredujete nizu, ki ga je treba izvesti po metodi subprocess.run, z argumentom input = 'string'.

uvoz podproces
izhod= podproces.teči(['mačka'], vnos='data.txt',zajem_izhod=Prav,
besedilo=Prav,preveri=Prav)
tiskanje (izhod)

Izvajanje zgornje kode bo ustvarilo naslednje rezultate:

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

Kot lahko vidite, zgornja koda podaja datoteko data.txt kot niz in ne kot datotečni objekt. Če želite datoteko data.txt posredovati kot datoteko, uporabite argument stdin.

z odprto('data.txt') kotf:
izhod= podproces.teči(['mačka'],stdin=f,zajem_izhod=Prav,
besedilo=Prav,preveri=Prav)
tiskanje (izhod)

Izvajanje zgornje kode bo ustvarilo naslednje rezultate:

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

Primer 6: Izvedite ukaz neposredno v lupini z uporabo metode Subprocess.run

Ukaz je mogoče zagnati neposredno v lupini, kakršen je, namesto da bi v glavnem ukazu uporabili niz, ki mu sledi, in možnosti, ki mu sledijo. Če želite to narediti, morate kot dodatni argument predati shell = True. Razvijalci pythona tega ne odvračajo, saj uporaba lupine = True lahko povzroči varnostne težave. Več o vplivih na varnost lahko preberete v tukaj .

uvoz podproces
podproces.teči('cat' data.txt '',lupina=Prav)

Izvajanje zgornje kode bo ustvarilo naslednje rezultate:

ime = Janez

Zaključek

Metoda subprocess.run v Pythonu je precej močna, saj omogoča izvajanje ukazov lupine v samem pythonu. To pomaga pri omejevanju vse kode na sam python brez potrebe po dodatni kodi skripta lupine v ločenih datotekah. Pravilno označevanje ukazov lupine na seznamu python pa je lahko precej težavno. Z metodo shlex.split () lahko označite preproste ukaze lupine, vendar v dolgih, zapletenih ukazih - zlasti tistih s simboli cevi - shlex ne uspe pravilno razdeliti ukaza. V takih primerih je lahko odpravljanje napak težavno vprašanje. Če se želite temu izogniti, uporabite argument shell = True, vendar so s tem dejanjem povezani nekateri varnostni pomisleki.