【问题标题】:How can I use Python curses with stdin?如何在标准输入中使用 Python 诅咒?
【发布时间】:2021-01-31 11:28:25
【问题描述】:

我正在尝试编写一个 Python 程序,它使用 curses 从标准输入显示/编辑文本。 我云实现了编辑模块,但我无法将标准输入作为输入。

我该如何解决这个问题?

import curses

def main(stdscr):
    while key := stdscr.getkey():
        stdscr.addstr(0, 0, key)

if __name__ == '__main__':
    curses.wrapper(main)
echo "hello" | python edit.py

Traceback (most recent call last):
  File "/path/to/edit.py", line 8, in <module>
    curses.wrapper(main)
  File "/path/to/.pyenv/versions/3.9.1/lib/python3.9/curses/__init__.py", line 94, in wrapper
    return func(stdscr, *args, **kwds)
  File "/path/to/edit.py", line 4, in main
    while key := stdscr.getkey():
_curses.error: no input

并且python edit.py(没有回显“hello”)成功完成。

【问题讨论】:

    标签: python curses


    【解决方案1】:

    首先,您必须从标准输入读取数据,而不是从 curses.getkey() 读取数据。

    所以你可以这样做先读取标准输入然后初始化然后在curses中显示内容:

    import sys
    import curses
    
    stdin_content = ()
    
    def main(stdscr):
        stdscr.clear() # and other curses init...
        while True:
            for i, line in enumerate(stdin_content):
                stdscr.addstr(2 + i, 2, "> " + line)
            stdscr.refresh()
            key = stdscr.getch()
            stdscr.timeout(1000)
            if key == ord('q'):
                break
    
    if __name__ == '__main__':
        stdin_content = sys.stdin.readlines()
        curses.wrapper(main)
    

    您可以启动:

    $ echo "hello" | python edit.py
    

    一切都很好,你显示一行或多行(如果你 cat 有多行)你在 ncurses 中传递给你的脚本。

    但是如果您之前阅读过标准输入,则会出现 getch() 无法正常工作的问题,因此即使应该这样做,您也无法使用 'q' 退出。

    @Frédéric Hamidi 在这里回答了这个问题: Linux: Pipe into Python (ncurses) script, stdin and termios 阅读他的答案以获取更多详细信息,但基本上你必须复制标准输入。

    ma​​in 中读取 stdin 后立即添加此行:

    os.dup2(3, 0)
    

    而不是这样调用:

    $ echo "hello" | python edit.py
    

    这样调用:

    $ (echo "hello" | python edit.py) 3<&0
    

    或者像这样在之前生成子shell:

    $ exec 3<&0  
    

    然后正常调用

    $ echo "hello" | python edit.py
    $ cat test.txt | python edit.py
    

    您可以阅读链接的答案和文档以进一步了解。 无论如何,希望这会有所帮助。

    【讨论】:

    • 太棒了!您可以投票并将答案设置为正确吗?
    • 很抱歉我的声望不够。所以我做不到。
    • 啊,好吧,我们的名声一样^^
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2014-04-23
    • 2016-07-07
    • 2018-12-21
    • 2012-04-08
    • 2019-12-14
    • 1970-01-01
    相关资源
    最近更新 更多