Search code examples
python-3.xpipestdin

In Python how do I read data from stdin until piped process terminates?


I'd like to do something like this:

data = json.load(open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin)

which for this example can be reduced to

data = json.load(sys.stdin)

But json.load runs a single .read() which might not contain the whole JSON string I provided via

generate_json_output | myprogram.py

Is there a recommended way to read from stdin until generate_json_output terminates? I tried to catch BrokenPipeError but it doesn't get raised when I run

while True:
    data += sys.stdin.read()

Solution

  • Instead of a while loop, you can use for loop like below to iterate over stdin.

    import sys
    
    data = ''
    for line in sys.stdin:
        data += line
    

    which can be written as one expression:

    data = "".join(sys.stdin)
    

    Running this with input generated using a pipe reads the stdin until it terminates.

    t.json:

    {
        'a': 2,
        'b': 3
    }
    

    Running cat t.json | python a.py prints the complete file to stdout.