0

I usually run a program from my OpenSuse linux terminal by typing ./run file_name. This will bring up a series of options that I can choose from by typing a numeric value 0-9 and hitting return on my keyboard. Now I want to do this from a python script automatically. My example below is not working, but I can't understand where I'm failing and how to debug:

import subprocess
p = subprocess.Popen(["/path/to/program/run", file_name], stdin = subprocess.PIPE,stdout=subprocess.PIPE,shell=False)
print "Hello"
out, err = p.communicate(input='0\r\n')
print out
print err
for line in p.stdout.readlines():
    print line

The output of this program is just

>> Hello
>>

i.e. then it seems to freeze (I have no idea whats actually happening!) I would have expected to see what I see when I run ./run file_name and hit 0 and then return directly in my terminal, but I assure you this is not the case. What can I do to debug my code?

Edit 1: as suggested in comments

import subprocess

fileName = 'test_profile'
p = subprocess.Popen(["/path/to/program/run", fileName], stdin = subprocess.PIPE,stdout=subprocess.PIPE,shell=False)
print "Hello"

for line in iter(p.stdout.readline,""):
    print line

will indeed return the stdout of my program!

11
  • Yes, it prints out Hello and then just waits... Commented Feb 15, 2016 at 18:41
  • Use for line in iter(p.stdout.readline,"") to get output in real time, if you want to continually communicate you will need to change your logic Commented Feb 15, 2016 at 18:42
  • I get nothing from that either! Commented Feb 15, 2016 at 18:47
  • 1
    for line in iter(p.stdout.readlines,"") is not what was suggest in the comments, readlines is not readline Commented Feb 15, 2016 at 18:54
  • 1
    Have you tried using 0\n rather than \0\r\n? Commented Feb 15, 2016 at 18:56

1 Answer 1

1

communicate waits for the completion of the program. For example:

import subprocess
p = subprocess.Popen(["cut", "-c2"], stdin=subprocess.PIPE, stdout=subprocess.PIPE,shell=False)
out, err = p.communicate(input='abc')
print("Result: '{}'".format(out.strip()))

# Result: 'b'

It sounds like you have a more interactive script, in which case you probably should try out pexpect

import pexpect

child = pexpect.spawn('cut -c2')
child.sendline('abc')
child.readline() # repeat what was typed
print(child.readline()) # prints 'b'
Sign up to request clarification or add additional context in comments.

2 Comments

Wow, i didn't know pexpect. My module of the month.
Ok yes thank you for the clarification. I need to send a sequence of inputs all corresponding to typing a number followed by return, and I know these before hand. I don't have access to pexpect unfortunately although it looks like what I need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.