Hoe Shell-opdrachten in Python uit te voeren met behulp van de Subprocess Run-methode

How Execute Shell Commands Python Using Subprocess Run Method



Subprocess is een ingebouwde Python-module die kan worden gebruikt om nieuwe processen te maken en om te communiceren met hun invoer- en uitvoergegevensstromen. In eenvoudiger bewoordingen kun je het gebruiken om shell-opdrachten uit te voeren en uitvoerbare binaire bestanden uit te voeren, meestal verspreid in verschillende bin-mappen over een Linux-bestandssysteem. U kunt ook een volledig pad naar een uitvoerbaar binair bestand opgeven en alle opdrachtregelopties gebruiken die aan het binaire bestand zijn gekoppeld. In dit artikel wordt uitgelegd hoe u de subprocesmodule en de uitvoeringsmethode ervan in Python-apps gebruikt. Alle codevoorbeelden in het artikel zijn getest met Python 3.8.2 op Ubuntu 20.04.

De methode Subproces.run

De methode Subproces.run heeft een lijst met argumenten nodig. Wanneer de methode wordt aangeroepen, voert deze de opdracht uit en wacht tot het proces is voltooid, waarbij uiteindelijk een CompletedProcess-object wordt geretourneerd. Het object CompletedProcess retourneert stdout, stderr, originele argumenten die zijn gebruikt tijdens het aanroepen van de methode en een retourcode. Stdout verwijst naar de gegevensstroom die door de opdracht wordt geproduceerd, terwijl stderr verwijst naar eventuele fouten die tijdens de uitvoering van het programma zijn opgetreden. Elke retourcode die niet nul is (exitcode) zou een fout betekenen met de opdracht die wordt uitgevoerd in de methode subproces.run.







Voorbeeld 1: Inhoud van een tekstbestand uitvoeren met behulp van de methode Subprocess.run

De onderstaande opdracht zal de inhoud van een data.txt-bestand uitvoeren, ervan uitgaande dat het een name=John-tekenreeks bevat.



importeren subproces
subproces.loop(['kat', 'data.txt'])

Als u de bovenstaande code uitvoert, wordt de volgende uitvoer geretourneerd:



naam=John
VoltooidProces(argumenten=['kat', 'data.txt'],retourcode=0)

Het eerste element van het lijstargument is de naam van de uit te voeren opdracht. Elk element in de lijst dat volgt op het eerste element wordt beschouwd als opdrachtregelopties of schakelopties. U kunt ook enkele streepjes en dubbele streepjes gebruiken om de opties te definiëren. Als u bijvoorbeeld bestanden en mappen in een map wilt weergeven, is de code subprocess.run([ls, -l]. In de meeste van deze gevallen kunt u elk door spaties gescheiden argument in een shell-opdracht beschouwen als een afzonderlijk element in de lijst die aan de methode subproces.run is geleverd.





Voorbeeld 2: Uitvoer van methode Subproces.run onderdrukken

Om de uitvoer van de methode subprocess.run te onderdrukken, moet u stdout=subprocess.DEVNULL en stderr=subprocess.DEVNULL als aanvullende argumenten opgeven.

importeren subproces

subproces.loop(['kat', 'data.txt'],stout=subproces.DEVNULL,
stderr=subproces.DEVNULL)

Als u de bovenstaande code uitvoert, wordt de volgende uitvoer geproduceerd:



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

Voorbeeld 3: Uitvoer vastleggen van methode Subproces.run

Gebruik een extra argument met de naam capture_output=True om de uitvoer van de methode subproces.run vast te leggen.

importeren subproces
uitvoer= subproces.loop(['kat', 'data.txt'],capture_output=Waar)
afdrukken (uitvoer)

Als u de bovenstaande code uitvoert, wordt de volgende uitvoer geproduceerd:

VoltooidProces(argumenten=['kat', 'data.txt'],retourcode=0,
stout=B'naam=JanN',stderr=B'')

U kunt afzonderlijk toegang krijgen tot stdout- en stderr-waarden door de methoden output.stdout en output.stderr te gebruiken. De uitvoer wordt geproduceerd als een bytereeks. Gebruik de methode output.stdout.decode(utf-8) om een ​​string als uitvoer te krijgen. U kunt ook text=True als extra argument opgeven voor de aanroep subproces.run om de uitvoer in tekenreeksindeling te krijgen. Om de exit-statuscode te krijgen, kunt u de output.returncode-methode gebruiken.

Voorbeeld 4: Uitzondering opheffen bij het mislukken van een opdracht uitgevoerd door de methode Subprocess.run

Als u een uitzondering wilt maken wanneer de opdracht wordt afgesloten met een status die niet nul is, gebruikt u het argument check=True.

importeren subproces
subproces.loop(['kat', 'data.tx'],capture_output=Waar,tekst=Waar,rekening=Waar)

Als u de bovenstaande code uitvoert, wordt de volgende uitvoer geproduceerd:

raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Commando '['cat', 'data.tx']'
geretourneerde uitgangsstatus niet-nul 1.

Voorbeeld 5: een tekenreeks doorgeven aan een opdracht die wordt uitgevoerd door de methode Subprocess.run

U kunt een tekenreeks doorgeven aan de opdracht die moet worden uitgevoerd door de methode subprocess.run door het argument input='string' te gebruiken.

importeren subproces
uitvoer= subproces.loop(['kat'], invoer='data.txt',capture_output=Waar,
tekst=Waar,rekening=Waar)
afdrukken (uitvoer)

Als u de bovenstaande code uitvoert, wordt de volgende uitvoer geproduceerd:

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

Zoals u kunt zien, geeft de bovenstaande code data.txt door als een tekenreeks en niet als een bestandsobject. Gebruik het argument stdin om data.txt als bestand door te geven.

met open('data.txt') alsF:
uitvoer= subproces.loop(['kat'],standaard=F,capture_output=Waar,
tekst=Waar,rekening=Waar)
afdrukken (uitvoer)

Als u de bovenstaande code uitvoert, wordt de volgende uitvoer geproduceerd:

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

Voorbeeld 6: Voer de opdracht rechtstreeks in Shell uit met behulp van de methode Subprocess.run

Het is mogelijk om een ​​commando direct in een shell uit te voeren zoals het is, in plaats van een string te gebruiken die is opgesplitst in het hoofdcommando en de opties die erop volgen. Om dit te doen, moet u shell=True als extra argument doorgeven. Dit wordt echter afgeraden door python-ontwikkelaars, omdat het gebruik van shell=True tot beveiligingsproblemen kan leiden. U kunt meer lezen over beveiligingsimplicaties van: hier .

importeren subproces
subproces.loop('kat 'data.txt'',schelp=Waar)

Als u de bovenstaande code uitvoert, wordt de volgende uitvoer geproduceerd:

naam=John

Conclusie

De methode subprocess.run in Python is behoorlijk krachtig, omdat je hiermee shell-opdrachten in python zelf kunt uitvoeren. Dit helpt bij het beperken van alle code tot python zelf zonder de noodzaak om extra shellscriptcode in afzonderlijke bestanden te hebben. Het kan echter behoorlijk lastig zijn om shell-commando's correct te tokeniseren in een python-lijst. Je kunt de shlex.split()-methode gebruiken om eenvoudige shell-commando's te tokeniseren, maar in lange, complexe commando's - vooral die met pipe-symbolen - slaagt shlex er niet in om het commando correct te splitsen. In dergelijke gevallen kan debuggen een lastig probleem zijn. U kunt het argument shell=True gebruiken om dit te voorkomen, maar er zijn bepaalde beveiligingsproblemen verbonden aan deze actie.