Hoe voer je een programma uit of roep je een systeemcommando op?

Hoe roep je een extern commando aan (alsof ik het had getypt bij de Unix-shell of Windows-opdrachtprompt) vanuit een Python-script?


Antwoord 1, autoriteit 100%

Gebruik de subprocess-module in de standaardbibliotheek:

import subprocess
subprocess.run(["ls", "-l"])

Het voordeel van subprocess.runboven os.systemis dat het is flexibeler (u kunt de stdout, stderr, de “echte” statuscode, beter foutafhandeling, enz…).

Zelfs de documentatie voor os.systemraadt aan om in plaats daarvan subprocesste gebruiken:

De module subprocessbiedt krachtigere faciliteiten voor het spawnen van nieuwe processen en het ophalen van hun resultaten; het gebruik van die module heeft de voorkeur boven het gebruik van deze functie. Zie het gedeelte Oudere functies vervangen door de subprocesmodulein de subprocessdocumentatie voor enkele handige recepten.

Gebruik op Python 3.4 en eerder subprocess.callin plaats van .run:

subprocess.call(["ls", "-l"])

Antwoord 2, autoriteit 61%

Hier is een samenvatting van de manieren om externe programma’s aan te roepen en de voor- en nadelen van elk:

  1. os.system("some_command with args")geeft het commando en de argumenten door aan de shell van je systeem. Dit is leuk omdat je op deze manier meerdere opdrachten tegelijk kunt uitvoeren en pijpen en invoer/uitvoer-omleiding kunt instellen. Bijvoorbeeld:

    os.system("some_command < input_file | another_command > output_file")  
    

Hoewel dit echter handig is, moet u het escapen van shell-tekens zoals spaties, enz. handmatig afhandelen. Aan de andere kant kunt u hiermee ook opdrachten uitvoeren die gewoon shell-opdrachten zijn en niet echt externe programma’s. Zie de documentatie.

  1. stream = os.popen("some_command with args")Doe hetzelfde als os.systembehalve dat het u een bestand-achtig geeft object dat u kunt gebruiken om toegang te krijgen tot de standaardinvoer / uitvoer voor dat proces. Er zijn 3 andere varianten van popen die allemaal de I / O enigszins anders verwerken. Als je alles als een reeks passeert, wordt je opdracht doorgegeven aan de schaal; Als u ze als een lijst passeert, hoeft u zich geen zorgen te maken over het ontsnappen van alles. Zie de documentatie .

  2. De PopenKLASSE VAN DE subprocessMODULE. Dit is bedoeld als vervanging voor os.popen, maar heeft het nadeel om iets ingewikkelder te zijn vanwege zo uitgebreid. U zou bijvoorbeeld zeggen:

    print subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read()
    

In plaats van:

   print os.popen("echo Hello World").read()

Maar het is leuk om alle opties daar in één uniforme klasse te hebben in plaats van 4 verschillende popenfuncties. Zie de documentatie .

  1. De callFunctie van de subprocessModule. Dit is eigenlijk net als de PopenKlasse en neemt alle dezelfde argumenten, maar wacht gewoon tot het opdracht is voltooid en geeft u de retourcode. Bijvoorbeeld:

    return_code = subprocess.call("echo Hello World", shell=True)  
    

    Zie de documentatie .

  2. Als u op Python 3,5 of hoger bent, kunt u de nieuwe subprocess.runfunctie, die veel op het bovenstaande is, maar zelfs flexibeler en retourneert een CompletedProcessobject wanneer de opdracht eindigt.

  3. De OS-module heeft ook alle Fork / Exec / Spawn-functies die u in een C-programma hebt, maar ik raad deze niet rechtstreeks aan.

De subprocessModule moet waarschijnlijk zijn wat u gebruikt.

Eindelijk bewust dat voor alle methoden waar u de definitieve opdracht passeert die door de schaal als een tekenreeks wordt uitgevoerd en u bent verantwoordelijk voor het ontsnappen. Er zijn ernstige beveiligingsimplicaties indien een deel van de tekenreeks die u passeert, niet volledig kan worden vertrouwd. Als een gebruiker bijvoorbeeld een of ander deel van de tekenreeks invoert. Als u niet zeker bent, gebruik deze methoden alleen met constanten. Om u een hint van de implicaties te geven, beschouwen deze code:

print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read()

En stel me voor dat de gebruiker iets binnenkomt “Mijn moeder had niet van me en amp; & amp; RM -RF /” die het hele bestandssysteem zou kunnen wissen.


3, Autoriteit 8%

Typische implementatie:

import subprocess
p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
    print line,
retval = p.wait()

Je bent vrij om te doen wat je wilt met de stdoutgegevens in de pipe. In feite kun je die parameters gewoon weglaten (stdout=en stderr=) en het zal zich gedragen als os.system().


Antwoord 4, autoriteit 5%

Enkele hints over het loskoppelen van het onderliggende proces van het aanroepende proces (het onderliggende proces op de achtergrond starten).

Stel dat u een lange taak wilt starten vanuit een CGI-script. Dat wil zeggen, het onderliggende proces zou langer moeten leven dan het uitvoeringsproces van het CGI-script.

Het klassieke voorbeeld uit de documentatie van de subprocesmodule is:

import subprocess
import sys
# Some code here
pid = subprocess.Popen([sys.executable, "longtask.py"]) # Call subprocess
# Some more code here

Het idee hier is dat je niet in de regel ‘call subprocess’ wilt wachten tot de longtask.py klaar is. Maar het is niet duidelijk wat er gebeurt na de regel ‘hier nog wat code’ uit het voorbeeld.

Mijn doelplatform was FreeBSD, maar de ontwikkeling was op Windows, dus ik zag het probleem eerst op Windows.

In Windows (Windows XP) wordt het bovenliggende proces pas voltooid als de longtask.py zijn werk heeft voltooid. Het is niet wat je wilt in een CGI-script. Het probleem is niet specifiek voor Python; in de PHP-gemeenschap zijn de problemen hetzelfde.

De oplossing is om DETACHED_PROCESS Process Creation Flagnaar de onderliggende CreateProcess-functie in Windows API.
Als je toevallig pywin32 hebt geïnstalleerd, kun je de vlag importeren uit de win32process-module, anders moet je het zelf definiëren:

DETACHED_PROCESS = 0x00000008
pid = subprocess.Popen([sys.executable, "longtask.py"],
                       creationflags=DETACHED_PROCESS).pid

/* UPD 2015.10.27@eryksun in een opmerking hieronder merkt op dat de semantisch correcte vlag CREATE_NEW_CONSOLE (0x00000010) is */

Op FreeBSD hebben we nog een ander probleem: wanneer het bovenliggende proces is voltooid, worden ook de onderliggende processen voltooid. En dat wil je ook niet in een CGI-script. Sommige experimenten toonden aan dat het probleem leek te zitten in het delen van sys.stdout. En de werkende oplossing was de volgende:

pid = subprocess.Popen([sys.executable, "longtask.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

Ik heb de code op andere platforms niet gecontroleerd en ken de redenen van het gedrag op FreeBSD niet. Als iemand het weet, deel je ideeën. Googlen op het starten van achtergrondprocessen in Python werpt nog geen licht.


Antwoord 5, autoriteit 3%

import os
os.system("your command")

Merk op dat dit gevaarlijk is, aangezien de opdracht niet wordt opgeschoond. Ik laat het aan jou over om te googlen voor de relevante documentatie over de ‘os’ en ‘sys’ modules. Er zijn een heleboel functies (exec* en spawn*) die soortgelijke dingen zullen doen.


Antwoord 6, autoriteit 3%

Ik raad aan om de module subprocesste gebruiken in plaats van os.system, omdat dit het geval is granaat ontsnapt voor u en is daarom veel veiliger.

subprocess.call(['ping', 'localhost'])

Antwoord 7, autoriteit 3%

import os
cmd = 'ls -al'
os.system(cmd)

Als u de resultaten van de opdracht wilt retourneren, kunt u gebruiken os.popen. Dit is echter verouderd sinds versie 2.6 ten gunste van de subprocesmodule, die andere antwoorden goed hebben behandeld.


Antwoord 8, autoriteit 2%

Er zijn veel verschillende bibliotheken waarmee je externe commando’s kunt aanroepen met Python. Voor elke bibliotheek heb ik een beschrijving gegeven en een voorbeeld getoond van het aanroepen van een extern commando. Het commando dat ik als voorbeeld heb gebruikt is ls -l(lijst alle bestanden). Als je meer wilt weten over een van de bibliotheken die ik heb vermeld en de documentatie voor elk van hen heb gekoppeld.

Bronnen

Dit zijn alle bibliotheken

Hopelijk helpt dit je bij het nemen van een beslissing over welke bibliotheek je gaat gebruiken 🙂

subproces

Subprocess stelt je in staat externe commando’s aan te roepen en deze te verbinden met hun input/output/error-pipes (stdin, stdout en stderr). Subproces is de standaardkeuze voor het uitvoeren van opdrachten, maar soms zijn andere modules beter.

subprocess.run(["ls", "-l"]) # Run command
subprocess.run(["ls", "-l"], stdout=subprocess.PIPE) # This will run the command and return any output
subprocess.run(shlex.split("ls -l")) # You can also use the shlex library to split the command

os

os wordt gebruikt voor “besturingssysteemafhankelijke functionaliteit”. Het kan ook worden gebruikt om externe commando’s aan te roepen met os.systemen os.popen(Opmerking: er is ook een subprocess.popen). os zal altijd de shell uitvoeren en is een eenvoudig alternatief voor mensen die dat niet hoeven of niet weten hoe subprocess.runte gebruiken.

os.system("ls -l") # Run command
os.popen("ls -l").read() # This will run the command and return any output

sh

sh is een subprocesinterface waarmee je programma’s kunt aanroepen alsof het functies zijn. Dit is handig als u een opdracht meerdere keren wilt uitvoeren.

sh.ls("-l") # Run command normally
ls_cmd = sh.Command("ls") # Save command as a variable
ls_cmd() # Run command as if it were a function

plumbum

plumbum is een bibliotheek voor “scriptachtige” Python-programma’s. U kunt programma’s aanroepen zoals functies zoals in sh. Plumbum is handig als u een pijplijn wilt laten lopen zonder de shell.

ls_cmd = plumbum.local("ls -l") # Get command
ls_cmd() # Run command

verwachting

Met

pexpect kun je onderliggende applicaties spawnen, ze besturen en patronen vinden in hun output. Dit is een beter alternatief voor subprocess voor commando’s die een tty verwachten op Unix.

pexpect.run("ls -l") # Run command as normal
child = pexpect.spawn('scp foo [email protected]:.') # Spawns child application
child.expect('Password:') # When this is the output
child.sendline('mypassword')

stof

fabric is een Python 2.5- en 2.7-bibliotheek. Hiermee kunt u lokale en externe shell-opdrachten uitvoeren. Fabric is een eenvoudig alternatief voor het uitvoeren van opdrachten in een beveiligde shell (SSH)

fabric.operations.local('ls -l') # Run command as normal
fabric.operations.local('ls -l', capture = True) # Run command and receive output

gezant

gezant staat bekend als ‘subproces voor mensen’. Het wordt gebruikt als een gemaksverpakking rond de module subprocess.

r = envoy.run("ls -l") # Run command
r.std_out # Get output

opdrachten

commandsbevat wrapper-functies voor os.popen, maar is verwijderd uit Python 3 omdat subprocesseen beter alternatief is.


Antwoord 9, autoriteit 2%

Met de standaard bibliotheek

Gebruik de subprocesmodule(Python 3):

import subprocess
subprocess.run(['ls', '-l'])

Dit is de aanbevolen standaardmanier. Meer gecompliceerde taken (pipes, output, input, enz.) kunnen echter vervelend zijn om te construeren en te schrijven.

Opmerking over Python-versie: als je nog steeds Python 2 gebruikt, subprocess.callwerkt op een vergelijkbare manier.

ProTip: shlex.splitkan helpen u de opdracht voor run, callen andere subprocess-functies ontleden voor het geval u niet wilt (of niet kunt!) geef ze in de vorm van lijsten:

import shlex
import subprocess
subprocess.run(shlex.split('ls -l'))

Met externe afhankelijkheden

Als je externe afhankelijkheden niet erg vindt, gebruik dan plumbum:

from plumbum.cmd import ifconfig
print(ifconfig['wlan0']())

Het is de beste subprocess-wrapper. Het is platformonafhankelijk, d.w.z. het werkt op zowel Windows- als Unix-achtige systemen. Installeren door pip install plumbum.

Een andere populaire bibliotheek is sh:

from sh import ifconfig
print(ifconfig('wlan0'))

Echter, shheeft de Windows-ondersteuning laten vallen, dus het is niet zo geweldig als het vroeger was. Installeren door pip install sh.


Antwoord 10, autoriteit 2%

Ik gebruik altijd fabricvoor dingen als:

from fabric.operations import local
result = local('ls', capture=True)
print "Content:/n%s" % (result, )

Maar dit lijkt een goed hulpmiddel te zijn: sh(Python-subprocesinterface).

Bekijk een voorbeeld:

from sh import vgdisplay
print vgdisplay()
print vgdisplay('-v')
print vgdisplay(v=True)

Antwoord 11, autoriteit 2%

Controleer ook de “pexpect” Python-bibliotheek.

Het zorgt voor interactieve besturing van externe programma’s/commando’s, zelfs ssh, ftp, telnet, etc. Je kunt gewoon zoiets typen als:

child = pexpect.spawn('ftp 192.168.0.24')
child.expect('(?i)name .*: ')
child.sendline('anonymous')
child.expect('(?i)password')

Antwoord 12

Als je de uitvoer nodig hebt van het commando dat je aanroept,
dan kun je subprocess.check_output(Python 2.7+) gebruiken.

>>> subprocess.check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'

Let ook op de parameter shell.

Als shell Trueis, wordt het opgegeven commando via de shell uitgevoerd. Dit kan handig zijn als u Python voornamelijk gebruikt voor de verbeterde besturingsstroom die het biedt over de meeste systeemshells en toch gemakkelijke toegang wilt tot andere shell-functies zoals shell-pipes, wildcards voor bestandsnamen, uitbreiding van omgevingsvariabelen en uitbreiding van ~ naar het huis van een gebruiker map. Merk echter op dat Python zelf implementaties biedt van veel shell-achtige functies (in het bijzonder glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser()en shutil).


Antwoord 13

Bijwerken:

subprocess.runis de aanbevolen aanpak vanaf Python 3.5als uw code niet compatibel hoeft te blijven met eerdere Python-versies. Het is consistenter en biedt hetzelfde gebruiksgemak als Envoy. (Piping is echter niet zo eenvoudig. Zie deze vraag voor hoe.)

Hier zijn enkele voorbeelden uit de documentatie.

Een proces uitvoeren:

>>> subprocess.run(["ls", "-l"])  # Doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)

Verhogen bij mislukte uitvoering:

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

Uitvoer vastleggen:

>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

Oorspronkelijk antwoord:

Ik raad aan om Envoyte proberen. Het is een wrapper voor subprocessen, die op hun beurt proberen te vervangende oudere modules en functies . Envoy is een subproces voor mensen.

Voorbeeld van gebruik van de README:

>>> r = envoy.run('git config', data='data to pipe in', timeout=2)
>>> r.status_code
129
>>> r.std_out
'usage: git config [options]'
>>> r.std_err
''

Ook dingen rondslingeren:

>>> r = envoy.run('uptime | pbcopy')
>>> r.command
'pbcopy'
>>> r.status_code
0
>>> r.history
[<Response 'uptime'>]

Antwoord 14

Zo voer ik mijn opdrachten uit. Deze code heeft vrijwel alles wat je nodig hebt

from subprocess import Popen, PIPE
cmd = "ls -l ~/"
p = Popen(cmd , shell=True, stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
print "Return code: ", p.returncode
print out.rstrip(), err.rstrip()

Antwoord 15

Gebruik subproces.

…of voor een heel eenvoudig commando:

import os
os.system('cat testfile')

Antwoord 16

Hoe een programma uit te voeren of een systeemcommando aan te roepen vanuit Python

Eenvoudig, gebruik subprocess.run, wat een CompletedProcess-object retourneert:

>>> from subprocess import run
>>> from shlex import split
>>> completed_process = run(split('python --version'))
Python 3.8.8
>>> completed_process
CompletedProcess(args=['python', '--version'], returncode=0)

(runwil een lijst met lexicaal geparseerde shell-argumenten – dit is wat je in een shell typt, gescheiden door spaties, maar niet waar de spaties tussen aanhalingstekens staan, dus gebruik een gespecialiseerde functie, split, om op te splitsen wat je letterlijk in je shell zou typen)

Waarom?

Vanaf Python 3.5 beveelt de documentatie subprocess.run:

De aanbevolen benadering voor het aanroepen van subprocessen is om de functie run() te gebruiken voor alle gebruikssituaties die het aankan. Voor meer geavanceerde toepassingen kan de onderliggende Popen-interface direct worden gebruikt.

Hier is een voorbeeld van het eenvoudigst mogelijke gebruik – en het doet precies wat gevraagd wordt:

>>> from subprocess import run
>>> from shlex import split
>>> completed_process = run(split('python --version'))
Python 3.8.8
>>> completed_process
CompletedProcess(args=['python', '--version'], returncode=0)

runwacht tot de opdracht is voltooid en retourneert vervolgens een CompletedProcess-object. Het kan in plaats daarvan TimeoutExpiredverhogen (als je het een timeout=argument geeft) of CalledProcessError(als het mislukt en je slaagt voor check=True).

Zoals je zou kunnen afleiden uit het bovenstaande voorbeeld, worden stdout en stderr beide standaard doorgesluisd naar je eigen stdout en stderr.

We kunnen het geretourneerde object inspecteren en het gegeven commando en de retourcode zien:

>>> completed_process.args
['python', '--version']
>>> completed_process.returncode
0

Uitvoer vastleggen

Als u de uitvoer wilt vastleggen, kunt u subprocess.PIPEdoorgeven aan de juiste stderrof stdout:

>>> from subprocess import PIPE
>>> completed_process = run(shlex.split('python --version'), stdout=PIPE, stderr=PIPE)
>>> completed_process.stdout
b'Python 3.8.8\n'
>>> completed_process.stderr
b''

En die respectievelijke attributen retourneren bytes.

Geef een commandolijst door

Je zou gemakkelijk kunnen overstappen van het handmatig verstrekken van een opdrachtreeks (zoals de vraag suggereert) naar het verstrekken van een tekenreeks die programmatisch is gebouwd. Bouw strings niet programmatisch op.Dit is een potentieel beveiligingsprobleem. Het is beter om aan te nemen dat u de invoer niet vertrouwt.

>>> import textwrap
>>> args = ['python', textwrap.__file__]
>>> cp = run(args, stdout=subprocess.PIPE)
>>> cp.stdout
b'Hello there.\n  This is indented.\n'

Let op, alleen argsmogen positioneel worden doorgegeven.

Volledige handtekening

Hier is de daadwerkelijke handtekening in de bron en zoals getoond door help(run):

def run(*popenargs, input=None, timeout=None, check=False, **kwargs):

De popenargsen kwargsworden gegeven aan de Popen-constructor. inputkan een reeks bytes zijn (of unicode, indien codering of universal_newlines=Truegespecificeerd) die naar de stdin van het subproces wordt doorgesluisd.

De documentatie beschrijft timeout=en check=Truebeter dan ik zou kunnen:

Het time-outargument wordt doorgegeven aan Popen.communicate(). Als de time-out
verloopt, wordt het onderliggende proces beëindigd en gewacht. De
TimeoutExpired uitzondering zal opnieuw worden verhoogd nadat het onderliggende proces heeft
beëindigd.

Als de controle waar is en het proces wordt afgesloten met een afsluitcode die niet nul is, a
CalledProcessError-uitzondering wordt gegenereerd. Attributen daarvan
uitzondering bevatten de argumenten, de exit-code en stdout en stderr if
ze werden gevangengenomen.

en dit voorbeeld voor check=Trueis beter dan het voorbeeld dat ik zou kunnen bedenken:

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

Uitgebreide handtekening

Hier is een uitgebreide handtekening, zoals aangegeven in de documentatie:

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, 
shell=False, cwd=None, timeout=None, check=False, encoding=None, 
errors=None)

Merk op dat dit aangeeft dat alleen de AGS-lijst positioneel moet worden doorgegeven. Dus geef de resterende argumenten door als trefwoordargumenten.

POPEN

Bij gebruik Popenin plaats daarvan? Ik zou moeite hebben om gebruiksbewijs alleen op de argumenten te vinden. Direct gebruik van Popenzou u echter toegang geven tot zijn methoden, waaronder poll, ‘send_signal’, ‘beëindigd’ en ‘wachten’.

Hier is de Popenhandtekening zoals gegeven in de bron . Ik denk dat dit de meest precieze inkapseling van de informatie is (in tegenstelling tot help(Popen)):


def __init__(self, args, bufsize=-1, executable=None,
             stdin=None, stdout=None, stderr=None,
             preexec_fn=None, close_fds=True,
             shell=False, cwd=None, env=None, universal_newlines=None,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False,
             pass_fds=(), *, user=None, group=None, extra_groups=None,
             encoding=None, errors=None, text=None, umask=-1, pipesize=-1):

Maar meer informatief is de PopenDocumentatie :

subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, 
stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None,
env=None, universal_newlines=None, startupinfo=None, creationflags=0, 
restore_signals=True, start_new_session=False, pass_fds=(), *, group=None, 
extra_groups=None, user=None, umask=-1, encoding=None, errors=None, 
text=None)

Voer een onderliggend programma uit in een nieuw proces. Op POSIX gebruikt de klas
os.execvp()-achtig gedrag om het onderliggende programma uit te voeren. Op Windows,
de klasse gebruikt de Windows CreateProcess()-functie. De argumenten om
Popen zijn als volgt.

Het begrijpen van de resterende documentatie over Popenwordt overgelaten als een oefening voor de lezer.


Antwoord 17

os.systemis OK, maar een beetje gedateerd. Het is ook niet erg veilig. Probeer in plaats daarvan subprocess. subprocessroept sh niet rechtstreeks aan en is daarom veiliger dan os.system.

Meer informatie hier.


Antwoord 18

Er is ook Plumbum

>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand(<LocalPath /bin/ls>)
>>> ls()
u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n'
>>> notepad = local["c:\\windows\\notepad.exe"]
>>> notepad()                                   # Notepad window pops up
u''                                             # Notepad window is closed by user, command returns

19

Het kan dit eenvoudig zijn:

import os
cmd = "your command"
os.system(cmd)

20

Gebruik:

import os
cmd = 'ls -al'
os.system(cmd)

os – Deze module biedt een draagbare manier om besturingssysteemafhankelijke functionaliteit te gebruiken.

Voor de meer os-functies, hieris de documentatie.


Antwoord 21

Er is hier nog een ander verschil dat niet eerder is genoemd.

subprocess.Popenvoert het <commando> als subproces. In mijn geval moet ik bestand <a> die moet communiceren met een ander programma, <b>.

Ik heb het subproces geprobeerd en de uitvoering is gelukt. Maar <b> kon niet communiceren met <a>.
Alles is normaal als ik beide vanaf de terminal uitvoer.

Nog een:
(OPMERKING: kwrite gedraagt zich anders dan andere applicaties. Als u het onderstaande met Firefox probeert, zullen de resultaten niet hetzelfde zijn.)

Als je os.system("kwrite")probeert, loopt het programma vast totdat de gebruiker kwrite sluit. Om dat te verhelpen probeerde ik in plaats daarvan os.system(konsole -e kwrite). Dit tijdprogramma bleef stromen, maar kwrite werd het subproces van de console.

Iedereen voert de kwrite uit die geen subproces is (d.w.z. in de systeemmonitor moet het aan de meest linkse rand van de boom verschijnen).


Antwoord 22

os.systemstaat je niet toe om resultaten op te slaan, dus als je resultaten in een of andere lijst wilt opslaan, werkt een subprocess.call.


Antwoord 23

subprocess.check_callis handig als u de retourwaarden niet wilt testen. Het genereert een uitzondering op elke fout.


Antwoord 24

Ik gebruik meestal subprocessamen met shlex(om het ontsnappen van strings tussen aanhalingstekens af te handelen):

>>> import subprocess, shlex
>>> command = 'ls -l "/your/path/with spaces/"'
>>> call_params = shlex.split(command)
>>> print call_params
["ls", "-l", "/your/path/with spaces/"]
>>> subprocess.call(call_params)

25

Ik schreef hiervoor een bibliotheek, shell.py .

Het is in feite een wrapper voor POPEN en SLEX voor nu. Het ondersteunt ook leidingopdrachten, zodat u opdrachten gemakkelijker in Python kunt keten. Dus je kunt dingen doen zoals:

ex('echo hello shell.py') | "awk '{print $2}'"

26

In Windows kunt u gewoon de subprocessModule importeren en externe opdrachten uitvoeren door subprocess.Popen(), subprocess.Popen().communicate()en subprocess.Popen().wait()zoals hieronder:

# Python script to run a command line
import subprocess
def execute(cmd):
    """
        Purpose  : To execute a command and return exit status
        Argument : cmd - command to execute
        Return   : exit_code
    """
    process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (result, error) = process.communicate()
    rc = process.wait()
    if rc != 0:
        print "Error: failed to execute command:", cmd
        print error
    return result
# def
command = "tasklist | grep python"
print "This process detail: \n", execute(command)

Uitgang:

This process detail:
python.exe                     604 RDP-Tcp#0                  4      5,660 K

27

U kunt POP gebruiken en vervolgens kunt u de status van de procedure controleren:

from subprocess import Popen
proc = Popen(['ls', '-l'])
if proc.poll() is None:
    proc.kill()

Uitchecken subprocess.popen .


28

Om het netwerk-ID van de openstack neutron :

#!/usr/bin/python
import os
netid = "nova net-list | awk '/ External / { print $2 }'"
temp = os.popen(netid).read()  /* Here temp also contains new line (\n) */
networkId = temp.rstrip()
print(networkId)

Uitvoer van nova net-lijst

+--------------------------------------+------------+------+
| ID                                   | Label      | CIDR |
+--------------------------------------+------------+------+
| 431c9014-5b5d-4b51-a357-66020ffbb123 | test1      | None |
| 27a74fcd-37c0-4789-9414-9531b7e3f126 | External   | None |
| 5a2712e9-70dc-4b0e-9281-17e02f4684c9 | management | None |
| 7aa697f5-0e60-4c15-b4cc-9cb659698512 | Internal   | None |
+--------------------------------------+------------+------+

Uitvoer van print(networkId)

27a74fcd-37c0-4789-9414-9531b7e3f126

Other episodes