1

I want to read output line by line

below is my bash code (meta.sh)

#!/bin/bash
echo "hello!"
read -p "Continue?(y/n)"
[ "$REPLY" == "y" ] || exit
echo "lol"

below is my subprocess code (test.py)

import subprocess
def create_subprocess(Command):
    proc = subprocess.Popen(
       Command,
       shell=True,
       stdout=subprocess.PIPE,
       stderr=subprocess.STDOUT,
       bufsize=1
      )
   return proc
Command = "/root/Desktop/meta.sh"
proc = create_subprocess(Command)
while True:
    line = proc.stdout.readline()
    if not line: break
    print line.strip()

now when i run "python test.py" it shows

hello!

now when I press y and press enter then it shows

Continue?(y/n)

lol

what ideally it should show is this

hello!

Continue?(y/n)

now when I press y and press enter then it should show

lol

Community
  • 1
  • 1
  • 3
    I think `readline` will read until a `\n` or `EOF` and the prompt line does not have either, so `readline` won't grab that first. You could perhaps read char by char instead of trying to read the whole line – Eric Renouf Jan 27 '16 at 20:16
  • readline is not reading until a `\n` comes because as `read` comes it stops therefore `Continue?(y/n)` is displayed after i press 'y'. What else should I use that reads until a `\n` or `EOF` comes – user3687970 Jan 28 '16 at 07:14

1 Answers1

1

As I mentioned in the comment, the problem is that python's readline is waiting until it gets either an end of line or end of file, neither of which are produced by the read -p command (note that you type onto the same line, because there is not a line ending on that one). That means your readline doesn't give you anything back until after lol is printed. You can get around this by reading one char at a time though, like so:

while True:
    cur = proc.stdout.read(1)
    if(not cur):
        break
    sys.stdout.write(cur)
    sys.stdout.flush()

though you'll have to import sys as well

This will display each character from proc.stdout as soon as it's read and not wait for newlines.

Eric Renouf
  • 13,950
  • 3
  • 45
  • 67
  • In general, if stdout is redirected to a pipe [the child process may use a block-buffering mode for its stdout](http://stackoverflow.com/q/20503671/4279). `.read(1)` won't help if it is the case (the output is delayed in the internal buffer inside the child process). Though I would expect the shell to flush the prompt text and therefore `.read(1)` should be enough, [e.g, `read_until()` function](http://stackoverflow.com/q/7897202/4279) – jfs Jan 29 '16 at 11:00