Search code examples
pythongrepsubprocesstornadostdin

Is there is any different between grep stdin and bc stdin?


There is some code like os.dup2 in tornado. It will redirect raw_input() content into a subprocess.

import os,sys
from tornado.ioloop import IOLoop
from tornado.gen import coroutine
from tornado.process import Subprocess as sp

@coroutine
def run(cmd):
    ioloop = IOLoop().current()
    proc = sp(cmd,shell=True,stdin=sp.STREAM, stdout=sp.STREAM, stderr=sp.STREAM)
    while 1:
        proc.stdin.write(raw_input('input: ')+'\n')
        print 'return: ', (yield proc.stdout.read_bytes(1024,partial=True)).strip()



IOLoop().current().run_sync(lambda :run(sys.argv[1]))

If we run bc command like python test.py bc, it will appear as follows:

# python sa.py bc
input: 1+1
return:  2
input:

But if I run with python test.py 'grep abc', will never return anything and hangs up.

input: abcdefg
return:  
(hanging up)

I guess that is there some difference between bc's stdin and grep's stdin. Can anybody tell me why? Thanks a lot.


Solution

  • There's no difference between standard input of the two commands. The difference is that bc reads one line of input and immediately prints the result. grep output is buffered by default so you won't immediately see output.

    You can try passing the --line-buffered option to grep which will output each line immediately.

    You should also keep in mind that grep may not produce a line of output for every line of output. This means that if you read in a line which is filtered out by grep, your program will hang trying to read the output (since there isn't any).