I can't get the following script to work without throwing an EOFError exception:
#!/usr/bin/env python3
import json
import sys
# usage:
# echo '[{"testname": "testval"}]' | python3 test.py
myjson = json.load(sys.stdin)
print(json.dumps(myjson))
answer = input("> ") # BUG: EOFError: EOF when reading a line
print(answer)
I've read this question which seems to be related: Python STDIN User Input Issue
I think that tells me I need to clear the stdin buffer ? But I'm not sure how because print(sys.stdin.readline())
just outputs a newline and the EOFError is still there.
I also tried using the sys.stdin.flush()
method (found in this question: Usage of sys.stdout.flush() method) although I still don't understand what it does because I couldn't find it in the official documentation (3.6), the closest I found was this but it doesn't mention flush: https://docs.python.org/3/library/sys.html
Please bear in mind that I'm not a programmer nor do I have a CS education or background. I just write scripts to automate parts of my, otherwise non-technical, work. So if you know any good beginner ressource on how stdin/stdout works in the shell with Python please do tell.
By piping input, Python is opening sys.stdin as a FIFO. Otherwise, Python will open sys.stdin to /dev/tty
or equivalent.
You can verify this with:
import os,sys,stat
print("isatty():", sys.stdin.isatty())
print("isfifo():", stat.S_ISFIFO(os.fstat(0).st_mode))
Run this twice, once piping in data, once not.
I get:
$ echo "Test" | ./test2.py
isatty(): False
isfifo(): True
$ ./test2.py
isatty(): True
isfifo(): False
So your EOF occurs because the FIFO sys.stdin is opened to is empty.
You can reopen sys.stdin to /dev/tty
, however.
j = json.load(sys.stdin)
print(j)
sys.stdin = open("/dev/tty")
answer = input("> ")
print(answer)
Which would work fine:
$ echo '{"key":"val"}' | python3 ./testjson.py
{'key': 'val'}
> testing
testing
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With