You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用subprocess调用SSH时伪终端分配及多命令执行问题

1. subprocess.run配置SSH伪终端的参数

报错Pseudo-terminal will not be allocated because stdin is not a terminal是因为SSH默认仅在本地标准输入为终端设备时分配伪终端,非交互场景下需要给SSH命令添加-tt参数强制分配伪终端。
subprocess.run的完整配置示例如下:

import subprocess
cmd = ["ssh", "-tt", "-i", "sshkey.pem", "user@111.1.1.1"]
# 单次执行exit命令
result = subprocess.run(
    cmd,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    input="exit\n",
    text=True
)
print(result.stdout)

2. 流式执行多条命令的实现

subprocess.run和Popen.communicate都仅支持单次输入输出,调用后会直接关闭管道,不满足多命令交互的需求。你需要直接操作Popen实例的标准输入、标准输出文件对象实现流式交互,注意需配合行缓冲、手动清空缓冲区操作,避免命令/输出滞留:

import subprocess

cmd = ["ssh", "-tt", "-i", "sshkey.pem", "user@111.1.1.1"]
p = subprocess.Popen(
    cmd,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    text=True,
    bufsize=1 # 开启行缓冲
)

# 定义读取命令输出的工具函数,可根据自身终端提示符调整终止条件
def read_output():
    output = []
    while True:
        line = p.stdout.readline()
        # 替换为你的SSH终端的提示符特征,比如root@xxx:~# 之类的内容
        if "user@111.1.1.1" in line:
            break
        if line:
            output.append(line.strip())
    return "\n".join(output)

# 执行第一条命令
p.stdin.write("ls -la\n")
p.stdin.flush()
print("ls命令输出:\n", read_output())

# 执行第二条命令
p.stdin.write("cd /opt && mkdir test\n")
p.stdin.flush()
print("创建目录命令执行完成")

# 执行第三条命令
p.stdin.write("pwd\n")
p.stdin.flush()
print("pwd命令输出:\n", read_output())

# 退出SSH会话
p.stdin.write("exit\n")
p.stdin.flush()
p.wait()

补充说明

如果存在复杂交互场景(比如sudo密码输入、特殊字符转义、长时间会话保活等),更推荐直接使用SSH协议库实现,不需要额外处理子进程管道的缓冲区、阻塞等问题,开发成本更低。

内容的提问来源于stack exchange,提问作者Gary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:45:04