我想用Python制作一个有点像fzf的程序——你通过管道传输输入,操纵它,然后它通过管道传输到其他东西。
我尝试过使用 urwid 在 Python 中制作这样的程序。如果我在程序中设置了一个假输入,它会按照我想要的方式工作,但是如果我通过管道输入(
cat foo.txt | python myprog.py
)我会收到错误。我怎样才能做到这一点?
特别是,我希望能够在关闭 stdin 之前启动 UI,与 fzf 相同。
举一个我遇到的问题的简单例子,给定这个程序:
import urwid
txt = urwid.Text("blah")
filler = urwid.Filler(txt)
def quitter(key):
if key == "q":
raise urwid.ExitMainLoop()
loop = urwid.MainLoop(filler, unhandled_input=quitter)
loop.run()
这个命令行:
ls | python script.py
出现此错误:
TypeError: ord() expected a character, but string of length 0 found
我不清楚为什么会发生这种情况,但例如看一下这个问题,它似乎确实与管道输入有关。
看起来执行此操作的方法是创建一个使用 tty 而不是 stdin 作为输入的
Screen
。然后必须将该屏幕对象传递到主循环。示例:
import urwid
txt = urwid.Text("blah")
filler = urwid.Filler(txt)
def quitter(key):
if key == "q":
raise urwid.ExitMainLoop()
tty_in = open('/dev/tty', 'r')
screen = urwid.raw_display.Screen(input=tty_in)
loop = urwid.MainLoop(filler, screen=screen, unhandled_input=quitter)
loop.run()
这个旧的邮件列表帖子让我半途而废。