在 python 中丢失标准输出数据



我正在尝试制作一个python脚本,该脚本将通过ssh在远程机器上运行bash脚本,然后解析其输出。bash 脚本在 stdout 中输出大量数据(如 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)                                                                                    

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

非常感谢您的任何提示!

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

与其检查退出状态,不如继续调用recv(2048)直到它返回一个空字符串,这意味着没有更多的数据出现:

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

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

output = stdout.read()

我可以建议一种不太粗糙的方式来通过 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

所有输出都已正确消耗

最新更新