【问题标题】:Paramiko ssh die/hang with big outputParamiko ssh 死机/挂起,输出量大
【发布时间】:2015-10-16 00:38:47
【问题描述】:

我尝试使用 Paramiko 和 ssh 调用 tar 命令来备份服务器。当文件数量有限时,一切正常,但当它是一个大文件夹时,脚本会无休止地等待。以下测试表明问题来自标准输出的大小。

有没有办法纠正并执行这种命令?

案例大输出:

query = 'cd /;ls -lshAR -h'
chan.exec_command(query)
while not chan.recv_exit_status():
    if chan.recv_ready():
        data = chan.recv(1024)
        while data:
            print data
            data = chan.recv(1024)

    if chan.recv_stderr_ready():
        error_buff = chan.recv_stderr(1024)
        while error_buff:
            print error_buff
            error_buff = chan.recv_stderr(1024)
    exist_status = chan.recv_exit_status()
    if 0 == exist_status:
        break

结果是(不正常 - 阻止 - 死亡 ??)

2015-07-25 12:57:07,402 --> Query sent

案例小输出:

query = 'cd /;ls -lshA -h'
chan.exec_command(query)
while not chan.recv_exit_status():
    if chan.recv_ready():
        data = chan.recv(1024)
        while data:
            print data
            data = chan.recv(1024)

    if chan.recv_stderr_ready():
        error_buff = chan.recv_stderr(1024)
        while error_buff:
            print error_buff
            error_buff = chan.recv_stderr(1024)
    exist_status = chan.recv_exit_status()
    if 0 == exist_status:
        break

结果是(一切正常)

2015-07-25 12:55:08,205 --> Query sent
total 172K
4.0K drwxr-x---   2 root psaadm 4.0K Dec 27  2013 archives
   0 -rw-r--r--   1 root root      0 Jul  9 23:49 .autofsck
   0 -rw-r--r--   1 root root      0 Dec 27  2013 .autorelabel
4.0K dr-xr-xr-x   2 root root   4.0K Dec 23  2014 bin
2015-07-25 12:55:08,307 --> Query executed (0.10) 

【问题讨论】:

标签: python ssh paramiko


【解决方案1】:

如果ls -R 打印出大量错误输出(如果当前用户不是root => 可能无法访问所有文件夹),那么您的代码最终将是deadlocks

这是因为,错误流的输出缓冲区最终会被填满,所以ls停止工作,等待你读取流(清空缓冲区)。

当您等待常规输出流完成时,它永远不会做,因为 ls 等待您读取错误流,而您永远不会做。

您必须并行读取两个流(请参阅Run multiple commands in different SSH servers in parallel using Python Paramiko)。

或者更简单,使用Channel.set_combine_stderr 将两个流合并为一个。

【讨论】:

    【解决方案2】:

    在检查退出状态之前读取数据

    channel.recv_exit_status() hanging

    【讨论】: