从paramiko ssh exec_command连续获取输出

Luk*_*ger 17 python ssh interactive stdout paramiko

我正在使用paramiko在远程机器上通过ssh执行长时间运行的python脚本.工作就像一个魅力,到目前为止没有问题.

不幸的是,stdout(分别是stderr)只在脚本完成后显示!但是,由于执行时间的原因,我更倾向于在打印时输出每个新行,而不是之后.

remote = paramiko.SSHClient()
remote.set_missing_host_key_policy(paramiko.AutoAddPolicy())
remote.connect("host", username="uname", password="pwd")

# myScript produces continuous output, that I want to capture as it appears    
stdin, stdout, stderr = remote.exec_command("python myScript.py")
stdin.close()
for line in stdout.read().splitlines():
    print(line)
Run Code Online (Sandbox Code Playgroud)

怎么能实现这一目标? 注意:当然可以通过另一个ssh会话将输出传输到文件并"减少"此文件,但这非常难看,我需要一个更清洁,理想的pythonic解决方案:)

Kur*_*tal 10

正如read([size])文档中所指定的那样,如果你没有指定a size,它会一直读到EOF,这会使脚本等到命令结束后再返回read()并打印任何输出.

检查这个答案:如何循环直到Python中的EOF?以及如何使用"虽然不是EOF"有关如何耗尽类文件对象的示例.

  • 感谢@KurzedMetal指出我正确的方向:`for line in iter(lambda:stdout.readline(2048),""):print(line,end ="")`...做了诀窍! (8认同)

Jam*_*rum 7

我面临着类似的问题.我能够通过向paramiko添加get_pty = True来解决它:

stdin, stdout, stderr = client.exec_command("/var/mylongscript.py", get_pty=True)
Run Code Online (Sandbox Code Playgroud)


Jor*_*tao 7

如何使用此答案的最小且完整的工作示例(在Python 3.6.1中测试)

# run.py
from paramiko import SSHClient

ssh = SSHClient()
ssh.load_system_host_keys()

ssh.connect('...')

print('started...')
stdin, stdout, stderr = ssh.exec_command('python -m example', get_pty=True)

for line in iter(stdout.readline, ""):
    print(line, end="")
print('finished.')
Run Code Online (Sandbox Code Playgroud)

# example.py, at the server
import time

for x in range(10):
    print(x)
    time.sleep(2)
Run Code Online (Sandbox Code Playgroud)

在本地机器上运行

python -m run
Run Code Online (Sandbox Code Playgroud)


小智 5

使用这个:

stdin, stdout, stderr = ssh.exec_command('python -m example', get_pty=True)

for line in iter(stdout.readline, ""):
    print(line, end="")
Run Code Online (Sandbox Code Playgroud)

来自 @JorgeLeitao 的回答将我的标准输出输出速度提高到几乎实时!

我正在使用:

stdin, stdout, stderr = ssh.exec_command(cmd)
for line in stdout:
    # Process each line in the remote output
        print (line)
Run Code Online (Sandbox Code Playgroud)