首页 > 解决方案 > Python `invoke` 不能在 Windows 上使用多行命令打印

问题描述

从 Windows使用调用库时,如果命令跨越多行,则似乎没有输出打印到终端。这是一个重现的例子;把这个放进去tasks.py

import invoke

@invoke.task
def test_oneline(ctx):
    ctx.run("pip install nonexistant-package1234")

@invoke.task
def test_multiline(ctx):
    ctx.run(
    """
    pip install nonexistant-package1234
    """
    )

然后,从与 相同目录中的命令提示符中tasks.py,我得到以下信息:

>invoke test-oneline
Collecting nonexistant-package1234
  Could not find a version that satisfies the requirement nonexistant-package1234 (from versions: )
No matching distribution found for nonexistant-package1234
>
>invoke test-multiline

>

在 Linux 上做同样的事情(好吧,至少是 Linux 的 Windows 子系统)按预期工作:

$ invoke test-multiline
Collecting nonexistant-package1234
  Could not find a version that satisfies the requirement nonexistant-package1234 (from versions: )
No matching distribution found for nonexistant-package1234
$

有没有办法在 Windows 中为多行命令打印输出?

标签: pythonwindowspyinvoke

解决方案


这是我现在正在使用的 hack,以防其他人需要在短期内规避这个问题。如果我遇到问题,我会回帖;到目前为止,它只进行了最低限度的测试。基本上,如果您在 Windows 上,我只需将命令写入.bat文件,然后运行该.bat文件(作为单行命令)。

import invoke
import platform
from pathlib import Path
from tempfile import TemporaryDirectory


def _fixed_run(ctx, cmd: str, *args, **kwargs):
    if platform.system() != "Windows":
        return ctx._old_run(cmd, *args, **kwargs)

    with TemporaryDirectory() as tmp_dir:
        tmp_file = Path(tmp_dir) / "tmp.bat"
        tmp_file.write_text("@echo off\r\n" + cmd)
        return ctx._old_run(str(tmp_file), *args, **kwargs)

invoke.Context._old_run = invoke.Context.run
invoke.Context.run = _fixed_run

要轻松使用它,请将其保存到文件中(例如fix_invoke.py,然后import fix_invoke在需要此修复时执行)。

不过,如果有人有一个真正的解决方案,我会很高兴!


推荐阅读