Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Paramiko:如何确保在命令之间接收数据_Python_Paramiko - Fatal编程技术网

Python Paramiko:如何确保在命令之间接收数据

Python Paramiko:如何确保在命令之间接收数据,python,paramiko,Python,Paramiko,我正在使用Paramiko发出许多命令并收集结果以供进一步分析。每隔一段时间,第一个命令的结果就会被及时完整地返回,并在第二个命令的输出中结束 我试图使用recv_ready来解释这一点,但它不起作用,所以我认为我做错了什么。以下是相关代码: pause = 1 def issue_command(chan, pause, cmd): # send commands and return results chan.send(cmd + '\n') while not c

我正在使用Paramiko发出许多命令并收集结果以供进一步分析。每隔一段时间,第一个命令的结果就会被及时完整地返回,并在第二个命令的输出中结束

我试图使用recv_ready来解释这一点,但它不起作用,所以我认为我做错了什么。以下是相关代码:

pause = 1

def issue_command(chan, pause, cmd):
    # send commands and return results
    chan.send(cmd + '\n')
    while not chan.recv_ready():
        time.sleep(pause)
    data = chan.recv(99999)

ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
chan = ssh.connect(host, port=22, username=username, password=password, timeout=3,)

resp1 = issue_command(chan, pause, cmd1)
resp2 = issue_command(chan, pause, cmd2)
这些命令的输出相对较小(只有几句话)。增加暂停可能会解决问题,但不是理想的解决方案


如有任何建议,将不胜感激

我将直接使用
传输
,并为每个命令创建一个新通道。然后,您可以使用以下内容:

def issue_command(transport, pause, command):
    chan = transport.open_session()
    chan.exec_command(command)

    buff_size = 1024
    stdout = ""
    stderr = ""

    while not chan.exit_status_ready():
        time.sleep(pause)
        if chan.recv_ready():
            stdout += chan.recv(buff_size)

        if chan.recv_stderr_ready():
            stderr += chan.recv_stderr(buff_size)

    exit_status = chan.recv_exit_status()
    # Need to gobble up any remaining output after program terminates...
    while chan.recv_ready():
        stdout += chan.recv(buff_size)

    while chan.recv_stderr_ready():
        stderr += chan.recv_stderr(buff_size)

    return exit_status, stdout, stderr

ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port=22, username=username, password=password, timeout=3,)
transport = ssh.get_transport()
pause = 1    

resp1 = issue_command(transport, pause, cmd1)
resp2 = issue_command(transport, pause, cmd2)
更好的方法是获取命令列表,并为每个命令生成一个新通道,轮询每个chan的
recv_ready
,并在输出可用时使用它们的stdout/stderr.:-)


编辑:在命令退出后读取数据存在潜在问题。请看评论

我想这让我走上了正确的道路。非常感谢。我需要为发出的每个命令创建一个新的连接和传输,因此我将ssh.connect和transport语句移动到issue_命令函数中。到目前为止效果良好。请注意,此解决方案可以工作,但不是防弹的-它仍然可以在收到所有数据之前退出,因为
recv_ready()
可以在通道流关闭之前返回
False
。更多详细信息:代码中有一个争用条件:在命令退出并且您检索到退出状态后,stdout或stderr缓冲区上可能仍然有数据。请参阅: