Context
我想要一个简单的脚本,它可以选择多个管道输入中的一个,而不需要EOF when reading a line
Unix/Linux 上的错误。
它试图:
- 接受多行管道文本
- 等待用户选择一个选项
- 将该选项打印到标准输出
所需用途:
$ printf "A\nB" | ./select.py | awk '{print "OUTPUT WAS: " $0}'
Select 0-1:
0) A
1) B
> 1
OUTPUT WAS: B
The awk '{print "[OUTPUT WAS] " $0}'
最后只是为了表明唯一的标准输出输出应该是选择。
目前的方法:
#!/bin/python3
import sys
from collections import OrderedDict
def print_options(options):
"""print the user's options"""
print(f"Select 0-{len(options)-1}:", file=sys.stderr)
for n, option in options.items():
print(f" {n}) {option}", file=sys.stderr)
def main():
# options are stored in an ordered dictionary to make order consistent
options = OrderedDict()
# read in the possible options one line at a time
for n, line in enumerate(sys.stdin):
options[n] = line.rstrip('\n')
valid_selection = False
# loop until we get a valid selection
while not valid_selection:
print_options(options)
try:
print('> ', end='', file=sys.stderr)
selection = int(input()) # <- doesn't block like it should
# use the selection to extract the output that will be printed
output = options[selection]
valid_selection = True
except Exception as e:
print(f"Invalid selection. {e}", file=sys.stderr)
print(output)
if __name__ == '__main__':
main()
Error:
该脚本陷入无限循环打印:
...
> Invalid selection. EOF when reading a line
Select 0-1:
0) A
1) B
> Invalid selection. EOF when reading a line
Select 0-1:
0) A
1) B
> Invalid selection. EOF when reading a line
...
重现错误的最小脚本:
#!/bin/python3
import sys
options = []
# read in the possible options one line at a time
for line in sys.stdin:
options.append(line.rstrip('\n'))
user_input = input('> ')
print(user_input)
这会抛出:
EOFError: EOF when reading a line
当我想查看并输入时:
$ printf "text" | ./testscript.py
> sometext
sometext
所需的解决方案:
我认为这是因为 stdin 已达到 EOF。但我的问题是如何重置/消除 EOF 的影响,以便input()
再次像平常一样阻塞并等待用户。
简而言之:如何使用input()
读取文件后stdin
?
如果那是不可能的话正如这个答案所暗示的 https://stackoverflow.com/a/6833677/7872793,有什么优雅的解决方案可以得到与我在这个问题开头描述的类似的行为?我对非 python 解决方案持开放态度(例如 bash|zsh、rust、awk、perl)。