Hvordan fange Python tolk og / eller Cmd.exe utgang fra et Python script?

stemmer
7
  1. Er det mulig å fange Python utgang fra et Python script?
  2. Er det mulig å fange Windows CMD utgang fra et Python script?

Hvis så, som bibliotek, (y | er) skal jeg se nærmere på?

Publisert på 24/08/2008 klokken 08:46
kilden bruker
På andre språk...                            


5 svar

stemmer
9

Hvis du snakker om Python eller cmd.exe som er 'foreldre' av skriptet så nei, det er ikke mulig. I hvert POSIX-lignende system (nå du kjører Windows, det virker, og som kan ha noen innfall jeg vet ikke om, YMMV) hver prosess har tre bekker, standard inngang, standard utgang og standard feil. Bu standard (ved kjøring i en konsoll) disse er rettet til konsollen, men omdirigering er mulig ved hjelp av rør notasjon:

python script_a.py | python script_b.py

Dette binder standard ut strømmen av skript en til inndatastrømmen av script B. Standardfeil likevel går til konsollen i dette eksempel. Se artikkelen på standard strømmer på Wikipedia.

Hvis du snakker om et barn prosess, kan du starte den fra python som så (stdin er også et alternativ hvis du ønsker toveis kommunikasjon):

import subprocess
# Of course you can open things other than python here :)
process = subprocess.Popen(["python", "main.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
x = process.stderr.readline()
y = process.stdout.readline()
process.wait()

Se Python subprosessen modulen for informasjon om styring av prosessen. For kommunikasjon blir process.stdin og process.stdout rør anses standard filobjekter .

For bruk med rør, leser fra standard inngang som lassevk foreslo du ville gjøre noe sånt som dette:

import sys
x = sys.stderr.readline()
y = sys.stdin.readline()

sys.stdin og sys.stdout er standard fil objekter som nevnt ovenfor, er definert i det sys -modulen. Du kan også være lurt å ta en titt på rør modulen.

Lese data med readline () som i mitt eksempel er en ganske naiv måte å få data om. Hvis utgangen er ikke linje-orientert eller indeterministic du sannsynligvis vil se nærmere polling som dessverre ikke fungerer i Windows, men jeg er sikker på at det er noen alternativ der ute.

Svarte 24/08/2008 kl. 09:39
kilden bruker

stemmer
4

Jeg tror jeg kan henvise deg til en god løsning for den første delen av spørsmålet ditt.

1. Er det mulig å fange Python utgang fra et Python script?

Svaret er " ja ", og personlig liker jeg følgende løftet fra eksemplene i PEP 343 - den "med" Statement dokument.

from contextlib import contextmanager
import sys

@contextmanager
def stdout_redirected(new_stdout):
    saved_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout.close()
        sys.stdout = saved_stdout

Og brukes slik:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

En fin aspekt ved det er at det kan påføres selektivt rundt bare en del av et skript s utførelse, snarere enn hele sin utstrekning, og forblir virksom selv når Ubehandlede unntak er hevet i løpet av sin sammenheng. Hvis du re-åpne filen i append-modus etter første gangs bruk, kan du samle resultatene i en enkelt fil:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

print "screen only output again"

with stdout_redirected(open("filename.txt", "a")):
    print "Hello world2"

Selvfølgelig, de ovennevnte kan også bli utvidet til også å omdirigere sys.stderrtil den samme eller en annen fil. Se også dette svaret til en beslektet spørsmål.

Svarte 31/07/2010 kl. 16:40
kilden bruker

stemmer
3

Egentlig du definitivt kan, og det er vakkert, stygt, og sprø på samme tid!

Du kan erstatte sys.stdout og sys.stderr med StringIO gjenstander som samler produksjonen.

Her er et eksempel, lagre det som evil.py:

import sys
import StringIO

s = StringIO.StringIO()

sys.stdout = s

print "hey, this isn't going to stdout at all!"
print "where is it ?"

sys.stderr.write('It actually went to a StringIO object, I will show you now:\n')
sys.stderr.write(s.getvalue())

Når du kjører dette programmet, vil du se at:

  • ingenting gikk til stdout (der print vanligvis skrives til)
  • den første strengen som blir skrevet til standardfeil er en starter med 'It'
  • de neste to linjene er de som ble samlet inn i StringIO objektet

Skifte sys.stdout / err som dette er en anvendelse av det som kalles monkeypatching. Meninger kan variere hvorvidt dette er 'støttet', og det er definitivt en stygg hack, men det har reddet mitt bacon når du prøver å vikle rundt ytre ting en gang eller to.

Testet på Linux, ikke på Windows, men det skal fungere like bra. La meg vite om det fungerer på Windows!

Svarte 26/08/2008 kl. 23:16
kilden bruker

stemmer
1

Du vil delprosess . Se spesielt på popen i 17.1.1 og kommunisere på 17.1.2.

Svarte 24/08/2008 kl. 09:27
kilden bruker

stemmer
0

I hvilken sammenheng spør du?

Prøver du å fange utgang fra et program du starter på kommandolinjen?

Hvis ja, så dette er hvordan man skal gjennomføre det:

somescript.py | your-capture-program-here

og å lese utgang, bare lese fra standard input.

Dersom, på den annen side, er du utfører dette skriptet eller cmd.exe eller lignende i programmet, og ønsker å vente til manuset / programmet er ferdig, og fange opp alle dens utgang, så du trenger å se på biblioteket kaller du bruke til å starte som eksternt program, mest sannsynlig er det en måte å be den gi deg noen måte å lese utgang og vente på ferdigstillelse.

Svarte 24/08/2008 kl. 09:05
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more