【问题标题】:Losing stdout data in python在python中丢失标准输出数据
【发布时间】:2023-03-13 08:13:02
【问题描述】:

我正在尝试制作一个 python 脚本,该脚本将通过 ssh 在远程机器上运行 bash 脚本,然后解析其输出。 bash 脚本在标准输出中输出大量数据(如 5 兆字节的文本/50k 行),这是一个问题 - 我仅在 ~10% 的情况下获取所有数据。在其他 90% 的情况下,我得到了我预期的 97% 左右,而且看起来它总是在最后修剪。这是我的脚本的样子:

import subprocess
import re
import sys
import paramiko

def run_ssh_command(ip, port, username, password, command):
    ssh = paramiko.SSHClient()    
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())                                                   
    ssh.connect(ip, port, username, password)                                                                   
    stdin, stdout, stderr = ssh.exec_command(command)                                                           
    output = ''                                                                                                 
    while not stdout.channel.exit_status_ready():                                                               
        solo_line = ''                                                                                          
        # Print stdout data when available                                                                      
        if stdout.channel.recv_ready():                                                                         
            # Retrieve the first 1024 bytes                                                                     
            solo_line = stdout.channel.recv(2048).                                                              
            output += solo_line                                                                                 
    ssh.close()                                                                                                 
    return output                                                                                  

result = run_ssh_command(server_ip, server_port, login, password, 'cat /var/log/somefile')
print "result size: ", len(result)                                                                                    

我很确定问题出在一些内部缓冲区溢出,但是是哪一个以及如何解决呢?

非常感谢您的任何提示!

【问题讨论】:

    标签: python linux bash ssh


    【解决方案1】:

    stdout.channel.exit_status_ready() 开始返回True 时,远程端可能仍有大量数据等待发送。但是你只收到一个 2048 字节的块并退出。

    您可以继续调用recv(2048),而不是检查退出状态,直到它返回一个空字符串,which means 表示没有更多数据到来:

    output = ''
    next_chunk = True
    while next_chunk:
        next_chunk = stdout.channel.recv(2048)
        output += next_chunk
    

    但实际上你可能只是想要:

    output = stdout.read()
    

    【讨论】:

      【解决方案2】:

      我可以建议一种不那么粗暴的方法来通过 Fabric 库在 ssh 上执行命令。 它可能看起来像这样(省略 ssh 身份验证详细信息):

      from fabric import Connection
      
      with Connection('user@localhost') as con:
          res = con.run('~/test.sh', hide=True)
          lines = res.stdout.split('\n')
          print('{} lines readen.'.format(len(lines)))
      

      给定测试脚本~/test.sh

      #!/bin/sh
      for i in {1..1234}
      do
        echo "Line $i"
      done
      

      所有输出都被正确消耗

      【讨论】:

        猜你喜欢
        • 2016-01-18
        • 2012-05-28
        • 2021-07-17
        • 2014-08-28
        • 1970-01-01
        • 2010-12-26
        • 2015-05-25
        • 1970-01-01
        • 2022-12-11
        相关资源
        最近更新 更多