Hello,
I have a strange problem with pexpect:
$ cat test.py
#!/usr/bin/python
import pexpect
child = pexpect.spawn("./test.pl")
while True:
try:
line = raw_input()
except EOFError:
break
child.sendline(line)
print child.readline().rstrip("\r\n")
child.close()
$ cat test.pl
#!/usr/bin/perl
# Replace all digits by __
while (<>) {
s/[0-9]+/__/g;
print;
}
$ echo bla24fasel | ./test.pl
bla__fasel
$ echo bla24fasel | ./test.py
bla24fasel
Why doesn't the last command return bla__fasel too?
I extracted this example from an even stranger problem in a bigger
program. In there, pexpect sometimes returns both the string send with
sendline() *and* the output of the child program, sometimes the
correct output of the child, and sometimes only the input it has send
to the child. I couldn't figure out a pattern, but the above example
always produces the same result.
You are reading back the echo of the data you sent to the child. This is expected behavior. This behavior can be confusing because you started a perl script and didn't program it to echo stdin. The reason is because the perl script is started in a pseudo-tty so there is actually a TTY device driver between your python script and your perl script. The TTY is echoing back stdin. This is the same thing that happens in a bash shell. You see what you type not because Bash is echoing but because the TTY device driver is echoing.
In Pexpect you can turn this off using child.setecho(False). See the doc string for "setecho()"
I rewrote your example to illustrate what is going on.
#!/usr/bin/python
import pexpect
child = pexpect.spawn("./test.pl")
print ("# Child echo mode: " + str(child.getecho()) )
print ("# Read one line from my stdin.")
try:
line = raw_input()
except EOFError, e:
print ("# Got EOFError from reading raw input. This is expected.")
print ("# Sending line read from raw_input to the child.")
child.sendline(line)
print ("# First: read and print a single line from the child.")
print child.readline().rstrip("\r\n")
print ("# Second: read and print a single line from the child.")
print child.readline().rstrip("\r\n")
print ("# Child echo mode: " + str(child.getecho()) )
print ("# Closing child.")
child.close()
The tracker form messes up the formatting of code, so I am submitting again. You should be able to fix the formatting even with indentation lost. Basically, the try clause has only one statement and the except clause also has only one statement.
#!/usr/bin/python
import pexpect
child = pexpect.spawn("./test.pl")
print ("# Child echo mode: " + str(child.getecho()) )
print ("# Read one line from my stdin.")
try:
line = raw_input()
except EOFError, e:
print ("# Got EOFError from reading raw input. This is expected.")
print ("# Sending line read from raw_input to the child.")
child.sendline(line)
print ("# First: read and print a single line from the child.")
print child.readline().rstrip("\r\n")
print ("# Second: read and print a single line from the child.")
print child.readline().rstrip("\r\n")
print ("# Child echo mode: " + str(child.getecho()) )
print ("# Closing child.")
child.close()