Conflict between sys.stdin and input() - EOFError: EOF when reading a line
Conflict between sys.stdin and input() - EOFError: EOF when reading a line
如果不抛出 EOFError 异常,我无法使以下脚本运行:
#!/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)
我读过这个似乎相关的问题:Python STDIN User Input Issue
我认为这告诉我需要清除标准输入缓冲区?但我不确定如何,因为 print(sys.stdin.readline())
只是输出一个换行符并且 EOFError 仍然存在。
我也尝试过使用sys.stdin.flush()
方法(在这个问题中找到: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
请记住,我不是程序员,也没有受过 CS 教育或背景。我只是编写脚本来自动化我的部分非技术工作。因此,如果您知道有关 stdin/stdout 如何在 shell 和 Python 中工作的任何好的初学者资源,请告知。
你真的不能 "clear" 标准输入 (stdin)。它在那里,可用于读取和许多输入函数读取直到文件结束(EOF,或标准输入结束)。 "flush" 操作用于标准输出。
在您的例子中,json.load(sys.stdin)
操作将读取整个标准输入(然后它将被关闭)。那时,没有更多的输入可用。
如果您既要读取输入数据又要获得来自用户的交互式输入,请考虑从文件中读取数据并仅使用标准输入进行交互式用户输入。
通过管道输入,Python 正在打开 sys.stdin 作为 FIFO。否则,Python 将打开 sys.stdin 到 /dev/tty
或等价物。
您可以通过以下方式验证:
import os,sys,stat
print("isatty():", sys.stdin.isatty())
print("isfifo():", stat.S_ISFIFO(os.fstat(0).st_mode))
运行 这两次,一次管道输入数据,一次没有。
我得到:
$ echo "Test" | ./test2.py
isatty(): False
isfifo(): True
$ ./test2.py
isatty(): True
isfifo(): False
所以你的 EOF 发生是因为 FIFO sys.stdin 打开 是 空的。
但是您可以重新打开 sys.stdin 到 /dev/tty
。
j = json.load(sys.stdin)
print(j)
sys.stdin = open("/dev/tty")
answer = input("> ")
print(answer)
哪个可以正常工作:
$ echo '{"key":"val"}' | python3 ./testjson.py
{'key': 'val'}
> testing
testing
如果不抛出 EOFError 异常,我无法使以下脚本运行:
#!/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)
我读过这个似乎相关的问题:Python STDIN User Input Issue
我认为这告诉我需要清除标准输入缓冲区?但我不确定如何,因为 print(sys.stdin.readline())
只是输出一个换行符并且 EOFError 仍然存在。
我也尝试过使用sys.stdin.flush()
方法(在这个问题中找到: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
请记住,我不是程序员,也没有受过 CS 教育或背景。我只是编写脚本来自动化我的部分非技术工作。因此,如果您知道有关 stdin/stdout 如何在 shell 和 Python 中工作的任何好的初学者资源,请告知。
你真的不能 "clear" 标准输入 (stdin)。它在那里,可用于读取和许多输入函数读取直到文件结束(EOF,或标准输入结束)。 "flush" 操作用于标准输出。
在您的例子中,json.load(sys.stdin)
操作将读取整个标准输入(然后它将被关闭)。那时,没有更多的输入可用。
如果您既要读取输入数据又要获得来自用户的交互式输入,请考虑从文件中读取数据并仅使用标准输入进行交互式用户输入。
通过管道输入,Python 正在打开 sys.stdin 作为 FIFO。否则,Python 将打开 sys.stdin 到 /dev/tty
或等价物。
您可以通过以下方式验证:
import os,sys,stat
print("isatty():", sys.stdin.isatty())
print("isfifo():", stat.S_ISFIFO(os.fstat(0).st_mode))
运行 这两次,一次管道输入数据,一次没有。
我得到:
$ echo "Test" | ./test2.py
isatty(): False
isfifo(): True
$ ./test2.py
isatty(): True
isfifo(): False
所以你的 EOF 发生是因为 FIFO sys.stdin 打开 是 空的。
但是您可以重新打开 sys.stdin 到 /dev/tty
。
j = json.load(sys.stdin)
print(j)
sys.stdin = open("/dev/tty")
answer = input("> ")
print(answer)
哪个可以正常工作:
$ echo '{"key":"val"}' | python3 ./testjson.py
{'key': 'val'}
> testing
testing