子进程标准输入不能与 less 作为进程一起使用

问题描述 投票:0回答:1

我有一个函数可以将输入文件呈现为自定义格式。 我希望用户可以在一个终端中启动此脚本,以使用寻呼机查看呈现的输出。 当他在另一个终端中编辑源文件并保存时,这些更改应该在寻呼机中重新呈现和更新。

检测这些变化并重新渲染它们是有效的。问题是寻呼机的更新。

经过一番搜索,我发现 less 可以在按“R”时执行此重新加载:

R                    Repaint screen, discarding buffered input.

所以我尝试在我的代码中实现此行为:

pager_process = subprocess.Popen(['less', filepath], stdin=subprocess.PIPE)
...
pager_process.stdin.write(b'R')  # HERE: this should reload less but doesn't

但这没有用。

有什么我不知道的想法或更深层次的知识吗?

原始代码
source = Path(source)  # some sort of input file

def render_source() -> str:
    try:
        return convert(fp=source)  # renders the input-file in a wished format
    except SyntaxError as error:
        return '\n'.join(traceback.format_exception(type(error), error, error.__traceback__))  # in case rendering fails

def update_tmpfile(new: str) -> None:
    tmp.truncate(0)
    tmp.seek(0)
    tmp.write(new)
    tmp.flush()

with tempfile.NamedTemporaryFile('w+') as tmp:
    last_mtime = source.stat().st_mtime_ns
    content = render_source()
    update_tmpfile(content)
    pager_process = subprocess.Popen(['less', tmp.name], stdin=subprocess.PIPE)

    try:
        while pager_process.poll() is None:  # not exited
            time.sleep(0.1)

            current_mtime = source.stat().st_mtime_ns
            if last_mtime != current_mtime:  # source changed -> rerender
                last_mtime = current_mtime

                content = render_source()
                update_tmpfile(content)
                pager_process.stdin.write(b'R')  # HERE: this should reload less but doesn't
    except Exception:
        pager_process.kill()
        raise
python python-3.x subprocess
1个回答
0
投票

经过一番研究,我终于找到了解决方案。

我使用 pypager 库

代替外部寻呼机进程

我用

创建了一个寻呼机实例
pager = pypager.Pager()
pager.add_source(pypager.StringSource(""))  # 0 index buffer
pager.add_source(pypager.StringSource(""))  # page-buffer that gets replaced

并且可以使用

更新渲染的内容
content = render_source()
pager.remove_current_source()
pager.add_source(pypager.StringSource(content))
pager.application.invalidate()
© www.soinside.com 2019 - 2024. All rights reserved.