【发布时间】:2021-05-14 11:51:56
【问题描述】:
上下文
我想要一个简单的脚本,在 Unix/Linux 上选择多个管道输入中的 1 个,而不会出现 EOF when reading a line 错误。
它试图:
- 接受多行管道文本
- 等待用户选择一个选项
- 将该选项打印到标准输出
所需用途:
$ printf "A\nB" | ./select.py | awk '{print "OUTPUT WAS: " $0}'
Select 0-1:
0) A
1) B
> 1
OUTPUT WAS: B
最后的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()
错误:
脚本陷入无限循环打印:
...
> 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
所需的解决方案:
我认为这是因为标准输入已达到 EOF。但我的问题是如何重置/消除 EOF 的影响,以便 input() 再次像往常一样阻塞并等待用户。
简而言之:从stdin读取文件后如何使用input()?
如果这是不可能的,as this answer implies,有什么优雅的解决方案可以得到与我在这个问题开头描述的类似的行为?我对非 python 解决方案持开放态度(例如 bash|zsh、rust、awk、perl)。
【问题讨论】:
-
@user 这不正确。如果您检查 while 循环,它的节会显示
while not valid_selection:检查最小脚本以重现我正在尝试修复的错误。编辑:用户删除了他们的评论,但我将把它留给其他人。
标签: python python-3.x shell scripting