web-dev-qa-db-ja.com

paramiko ssh exec_commandから継続的に出力を取得します

私は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)

これはどのように達成できますか?注:もちろん、出力をファイルにパイプし、別のsshセッションを介してこのファイルを「小さく」することもできますが、これは非常にいですそして、よりクリーンで理想的にはPythonのソリューションが必要です:)

16

read([size])ドキュメント で指定されているように、sizeを指定しない場合、EOFまで読み取ります。これにより、read()から戻って出力を出力する前に、コマンドが終了するまでスクリプトが待機します。

この回答を確認してください: PythonでEOFまでループする方法? および 「EOFではない」を行う方法 方法の例Fileのようなオブジェクトを使い果たします。

10
KurzedMetal

this answer (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.')

そして

# example.py, at the server
import time

for x in range(10):
    print(x)
    time.sleep(2)

ローカルマシンで実行する

python -m run
7
Jorge Leitao

私は同様の問題に直面していました。 paramikoにget_pty = Trueを追加することで解決できました。

stdin, stdout, stderr = client.exec_command("/var/mylongscript.py", get_pty=True)
7
James Shrum