Python3 subprocess.run - 如何打印/捕获输出(stdout、stderr),同时还允许用户输入(stdin)

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

为了方便起见,我正在尝试创建一个可以从 python 运行 bash 命令的函数。我想输出任何标准输出,同时还存储所有标准输出/标准错误以供参考。然而,当涉及用户输入时,我似乎遇到了问题。在下面的示例中,stdout 无法打印(根本没有显示任何内容),直到按下 Enter 键,这会立即跳过 stdin。

设置子进程 stdin=subprocess.PIPE 没有帮助,这会完全跳过任何用户输入

import subprocess

def run_command(command):
    result = {}
    try:
        process = subprocess.run(
            command,
            shell=True,
            stdin=None, #setting to subprocess.PIPE skips userinput entirely
            stdout=None,
            stderr=None,
            universal_newlines=True,
            capture_output=True
        )

        result = {
            "returncode": process.returncode,
            "stdout": process.stdout,
            "stderr": process.stderr
        }

        #when a command requests userinput, this doesn't seem to print UNTIL enter is hit
        print(process.stdout)

    except Exception as e:
        print(f"Exception occurred: {e}")

    return result

#Example: has an issue when run a second time, because stdin for existing file overwrite
result = run_command(f"ssh-keygen -t ed25519 -N '' -f ./ssh_key_test")
print(result)

python python-3.x subprocess
1个回答
0
投票

在这种特殊情况下,有两种不同的方法:

  1. 生成前删除关键文件
  2. 使用
    yes
    命令

在这两种方法中,我喜欢第一种,因为它可以跨平台工作。第二种方法仅适用于具有可用

yes
命令的操作系统。

删除关键文件

import subprocess
import pathlib

# Removing any existing keys
filename = "./ssh_key_test"
pathlib.Path(filename).unlink(missing_ok=True)
pathlib.Path(f"{filename}.pub").unlink(missing_ok=True)

# Generate
cmd = subprocess.run(
    ["ssh-keygen", "-t", "ed25519", "-N", '', "-f", filename],
)

使用
yes
命令

#!/usr/bin/env python3
import subprocess

cmd = subprocess.run(
    "yes | ssh-keygen -t ed25519 -N '' -f ./ssh_key_test",
    shell=True,
)
© www.soinside.com 2019 - 2024. All rights reserved.