Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Python: Kuinka ohjataan toista konsoliohjelmaa Linuxissa?

peran [06.10.2015 12:43:48]

#

Ongelmia ulkoisen ohjelman ohjauksessa pythonin avulla.

Tarkoitus olisi saada ohjattua gnuchess ulkoisella ohjelmalla ilman shakkiohjelman sulkemista.

Tällaista olen räpeltänyt, mutta se ei aivan toimi kuten haluaisin, vaan ohjelma pitää lopettaa ennen kuin pystyn lukemaan stdout:in tulostamaa tekstiä. Tavoitteena olisi, ettei tarvitsisi lopettaa quit-toiminnolla ennen kuin toinen pelaaja on ajautunut mattiin.

Sitten koodia...
Toimiva ohjelma, mutta gnuchess ohjelman suoritus lopetetaan quit-käskyllä ennen kuin pystyy luekemaan ohjelman tulostuksen.

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import subprocess
engine = subprocess.Popen('/usr/games/gnuchess' , engine.stdin=subprocess.PIPE, engine.stdout=subprocess.PIPE,)
engine.stdin.write(bytes('e2e4\n','UTF-8'))
engine.stdin.write(bytes("quit\n", 'UTF-8'))
for line in engine.stdout:
	print(engine.stdout.read().decode('UTF-8'))

Tämä siis jää odottamaan, eikä suorita loppuun engine.stdout.read().decode('UTF-8') ennen kuin katkaisen näppäimistön avulla suorituksen.

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import subprocess
engine = subprocess.Popen('/usr/games/gnuchess' , engine.stdin=subprocess.PIPE, engine.stdout=subprocess.PIPE,)
engine.stdin.write(bytes('e2e4\n','UTF-8'))
#engine.stdin.write(bytes("quit\n", 'UTF-8'))
for line in engine.stdout:
	print(engine.stdout.read().decode('UTF-8'))

Myös toimiva versio netcat-ohjelman avulla toimivasta ratkaisusta olen kiinnostunut.

Chiman [06.10.2015 14:46:15]

#

Oletko kokeillut käyttää engine.communicate-metodia?
https://docs.python.org/2/library/subprocess.html#subprocess.Popen.communicate

peran [06.10.2015 15:03:16]

#

Chiman kirjoitti:

Oletko kokeillut käyttää engine.communicate-metodia?

Hyvä kun muistutitte, sitähän nimenomaan olinkin yrittänyt käyttää, eli toimiva on seuraavanlainen (Tätä sählätessä on mennyt osittain toimivatkin ratkaisut bittitaivaaseen...)...

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import subprocess
import sys
std=sys.stdout
engine = subprocess.Popen(['/usr/games/gnuchess'] , stdin=subprocess.PIPE, stdout=subprocess.PIPE)
engine.stdin.write(bytes("e2e4\n",'UTF-8'))
engine.stdin.write(bytes("quit\n", 'UTF-8'))
for line in engine.communicate():
	print(line)

... ja toimimaton, jonka haluaisin toimivan...

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import subprocess
import sys
std=sys.stdout
engine = subprocess.Popen(['/usr/games/gnuchess'] , stdin=subprocess.PIPE, stdout=subprocess.PIPE)
engine.stdin.write(bytes("e2e4\n",'UTF-8'))
for line in engine.communicate():
	print(line)
engine.stdin.write(bytes("quit\n", 'UTF-8'))

Edit - Siis jälkimmäisessä tapauksessa prosessi jää päälle ennen rivin tulostamista, mutta ei siis tulosta sitä osaakaan, jonka ohjelma on jo tulostanut.

Lisäys:

Tällaisella koodilla, näkyy toimivan, vaikka onkin suurta purkkaa...

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import subprocess
from subprocess import PIPE, Popen
import sys
std=sys.stdout
p = subprocess.Popen(['/usr/games/gnuchess'] , stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
p.stdin.write("e2e4\n")
one_line_output = p.stdout.readline()
print (one_line_output)
one_line_output = p.stdout.readline()
print (one_line_output)
one_line_output = p.stdout.readline()
print (one_line_output)
one_line_output = p.stdout.readline()
print (one_line_output)
one_line_output = p.stdout.readline()
print (one_line_output)


one_line_output = p.stdout.readline()
print (one_line_output)
one_line_output = p.stdout.readline()
print (one_line_output)
one_line_output = p.stdout.readline()
print (one_line_output)
one_line_output = p.stdout.readline()
print (one_line_output)
one_line_output = p.stdout.readline()
print (one_line_output)

p.stdin.write('quit\n')

Edit - Siis kiitoksia Chiman:lle ja Googlelle.

Metabolix [06.10.2015 18:52:42]

#

peran, oletko kuullut esim. silmukasta?

for i in range(0, 10): # tai: while True:
	print(p.stdout.readline())

peran [06.10.2015 19:07:55]

#

Metabolix kirjoitti:

peran, oletko kuullut esim. silmukasta?

Toki ;D, mutta tässä pitäisi saada nuuskittua / heitettyä poikkeus, mikäli bufferissa ei ole enää rivinvaihtoja. Kyseinen esimerkkini ei tietenkään ollut lopullista koodia.

Toki nykyisestäkin pystyy nuuskimaan juuri ennen rivinvaihtoa olevan vakiotiedon.

Jos laittaa tuon while Truen, niin sitten siitä kannattaneen tehdä oma säikeensä.
Se pitäneen tehdä, mikäli en keksi hienostuneempaa tapaa.

Lisäys:

Valitettavasti minun 'toimiva' esimerkki toimii vain Python2:ssa.

Pitääköhän tehdä sillä, jolla osaa eikä sillä millä olisi parasta ?

Lisäys:

No, vihdoinkin sain python3-esimerkin toimimaan...

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import subprocess
from subprocess import PIPE, Popen
#import subprocess
import sys
std=sys.stdout
p = subprocess.Popen('/usr/games/gnuchess' , stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
p.stdin.write(bytes("e2e4\n","UTF-8"))
p.stdin.flush()

one_line_output = p.stdout.readline()
print (str(one_line_output,'UTF-8'))

one_line_output = p.stdout.readline()
print (str(one_line_output,'UTF-8'))
one_line_output = p.stdout.readline()
print (str(one_line_output,'UTF-8'))
one_line_output = p.stdout.readline()
print (str(one_line_output,'UTF-8'))
one_line_output = p.stdout.readline()
print (str(one_line_output,'UTF-8'))
one_line_output = p.stdout.readline()
print (str(one_line_output,'UTF-8'))
one_line_output = p.stdout.readline()
print (str(one_line_output,'UTF-8'))
one_line_output = p.stdout.readline()
print (str(one_line_output,'UTF-8'))
p.stdin.write(b'quit\n')

Eli piti tyhjentää puskuri. (Ja edelleenkään en käytä pikkuesimerkissäni silmukoita.)

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta