2012-02-09 13 views
11

Actualmente estoy pasando una cierta entrada a un proceso con pexpect con el siguiente código:pexpect no puede pasar entrada más de 1024 caracteres?

p = pexpect.spawn('cat', timeout=5.0) 
p.maxread = 5000 
p.setecho(False) # prevent the process from echoing stdin back to us 
INPUT_LEN = 1024 
p.sendline('a'*INPUT_LEN) 
print p.readline() # pexpect.TIMEOUT: Timeout exceeded in read_nonblocking(). 

Cuando INPUT_LEN < 1024, todo funciona bien, pero de> = 1024 caracteres, el proceso no recibe la plena entrada, lo que provoca la aparición de un error "pexpect.TIMEOUT" en p.readline().

He intentado dividir mi entrada en pedazos más pequeños de 1.024 caracteres, pero esto tiene el mismo problema:

p = pexpect.spawn('cat', timeout=5.0) 
p.maxread = 5000 
p.setecho(False) 
INPUT_LEN = 1024 
p.send('a'*1000) 
p.sendline('a'*(INPUT_LEN-1000)) 
print p.readline() # pexpect.TIMEOUT: Timeout exceeded in read_nonblocking(). 

¿Alguien sabe cómo hacer el trabajo pexpect con entradas de más de 1024 caracteres? Traté de ver la fuente, pero parece que está llamando a os.write (...).

(Como nota al margen, he notado que se produce el mismo error de truncamiento cuando ejecuto "cat" desde un shell e intento pegar> = 1024 caracteres con "Cmd + V". Sin embargo, todo funciona bien si corro "pbpaste | cat")

Gracias.!

Actualización: el llamado a "os.write()" devuelve 1025, lo que indica una escritura con éxito, pero os.read() devuelve "\ x07" (el único personaje BEL), y luego se cuelga en la próxima llamada, lo que resulta en el tiempo de espera.

Dividir la llamada os.write() en dos sub-1024 byte write() s, separados por una llamada a os.fsync(), no cambia nada.

+0

'pexpect.spawn' debe tener una palabra clave' maxdata', por defecto, a '2000', así que probablemente esto suele aplicarse a su caso, pero ¿ha tratado aumentarla ? –

+0

Desafortunadamente eso no funcionó; ver la última edición – tba

+0

Disculpe la confusión, escribí maxdata pero quise decir 'maxread', bueno, valió la pena intentarlo, supongo. –

Respuesta

5

Su problema parece estar relacionado MacOS, echar un vistazo a MacOSX 10.6.7 cuts off stdin at 1024 chars.

Básicamente dice que 1024 es el límite de búfer TTY.

no soy un experto en Mac OS, pero tal vez otros le puede dar más información sobre esto.

+0

¿Alguna recomendación sobre cómo solucionar esto a nivel de Python? p.ej. escribiendo 1023 bytes, vaciando los búferes, y luego escribiendo el resto? – tba

+0

@tba: Según lo que estás explicando, el problema parece estar en el lado de lectura.Así que creo que estás apilado con un enfoque de tubería (como el que tiene pbpaste), pero me temo que probablemente anule tu esfuerzo de usar Pexpect. –

+0

Desafortunadamente, el uso de tuberías con el "subproceso" de python provoca interbloqueos: consulte "Advertencia:" sobre el uso de ".stdin.write" en http://docs.python.org/library/subprocess.html. La solución sugerida es usar comunicar(), que espera a que el proceso finalice. Esto no funcionará para mí porque necesito enviar y recibir información con el proceso varias veces antes de que finalice. – tba

1

Me di cuenta que es muy, muy tarde, pero estoy publicando una solución para alguien que tropieza a esta pregunta con el mismo problema (como lo hice el día de hoy).

Basado en algunas de las respuestas/comentarios, he escrito un paquete pexpect like que usa stdin.write y stdout.read en lugar de lo que sea que pexpect use. No he tenido la oportunidad de probarlo muy bien, pero hasta este punto, se ha enfrentado al desafío.

Puede encontrar el código aquí: https://github.com/tayyabt/tprocess

Cuestiones relacionadas