Python Paramiko stdout 多进程 阻塞 卡住 问题解决

使用paramiko进程远程操作时,如果缓冲区满了,exec_command在写入该缓冲区时会产生阻塞并一直保持阻塞状态,直到缓冲区被清空为止。

使用multiprocessing无疑会加重这种情况,其中一种解决办法是设置exec_command的get_pty参数为True:

def ssh_command(cmd, ip, port, user, passwd, out):
    ssh = paramiko.SSHClient()
    # ssh._transport = transport
    """
    The authenticity of host '172.25.254.221 (172.25.254.221)' can't be established.
    ECDSA key fingerprint is 4c:98:51:43:65:46:66:fd:af:5b:ea:cc:d9:97:c0:74.
    Are you sure you want to continue connecting (yes/no)?
    """
    # 自动选择yes
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        print('ssh.connect: {} port: {}, command: {}'.format(ip, port, cmd))
        ssh.connect(ip, port, user, passwd, allow_agent=False)
    except Exception as e:
        ssh.close()
        out.append(e)
        return ERROR_SSH_CONNECT_FAILED

    stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True)
    # 实时输出
    while not stdout.channel.exit_status_ready():
        result = stdout.readline()
        out.append(result)
        if stdout.channel.exit_status_ready():
            result = stdout.readline()
            out.append(result)
    ssh.close()

    return 0

SSHClient的相关介绍:

https://www.cnblogs.com/caesar-id/p/12873557.html

class paramiko.client.SSHClient

SSHClient是与SSH服务器回话的高级封装,其内部实现了身份验证,执行命令等大多数基础功能。

exec_command(
command,
bufsize=-1,
timeout=None,
get_pty=False,
environment=None,
)

command(str):要执行的命令,多条命令用分号隔开。

bufsize(int):0 表示不缓冲,如果为 1 表示进行行缓冲,大于 1 为缓冲区大小。

timeout(float):命令执行的超时时间,单位秒。

get_pty(bool):如果为True相当于Channel.get_pty,向服务器请求一个伪终端。

environment(dict):在执行命令时附加环境变量。

返回值:返回一个元组 (stdin, stdout, stderr)

class paramiko.channel.Channel(chanid)

channel是一个SSH传输的安全隧道。一个通道类似于一个socket,由于SSH2有一种窗口式的流控制,如果停止从channel中读取数据,并且其缓冲区已满,服务器将无法向channel发送更多的数据,直到从channel中读取其中一些数据。(注意:这不会影响同一传输上的其他channel,单个传输上的所有channel都是独立的流控制。)同样,如果服务器不读取channel发送的数据,则除非设置超时,否则发送调用会一直处于阻塞。

get_pty(term="vt100",width=80,height=24,width_pixels=0,height_pixels=0)

功能:向服务器请求获取一个伪终端,通常在创建channel后,立即调用get_pty()请求一个伪终端,在使用invoke_shell想要创建一个交互式shell环境时需要提前调用get_pty(),如果调用的是exec_command执行命令,不需要使用get_pty()。

参考资料:

https://www.cnblogs.com/xiaofeng91/p/15070097.html

paramiko的get_pty=True参数_莺声门径的博客-CSDN博客_get_pty=true

关于python:读取大输出时,Paramiko通道卡住 | 码农家园

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值