2017-06-12 12 views
1

Pythonでリモートサーバ上でコマンドを実行し、stdoutをローカルコマンドにパイプする方法はありますか? Pythonでssh host 'echo test' | catを行うために、私はParamikoのstdoutをサブプロセスのstdinとして使用する

import paramiko 
import subprocess 

ssh = paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect('host', username='user') 
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('echo test') 
proc = subprocess.Popen(['cat'], stdin=ssh_stdout) 
outs, errs = proc.communicate() 
print(outs) 

を試してみましたが、私は例外'ChannelFile' object has no attribute 'fileno'を取得します。 Paramikoのssh_stdoutは、subprocess.Popenでstdinとして使用できないようです。

答えて

1

はい、subprocessは、出力を「偽の」ファイルにリダイレクトできません。 filenoが必要です。これは "実際の"ファイルでのみ定義されています(io.BytesIO()にはそれもありません)。私は次のコードのように手動でそれを行うだろう

は示しています。

proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE) 
proc.stdin.write(ssh_stdout.read()) 
proc.stdin.close() 

ので、あなたが入力パイプであることPopenを言っている、とあなたは、パイプ内のsshの出力データを書き込む(およびクローズそれでcatはいつ終わらなければならないかを知っています)

1

文書によると、ChannelFileオブジェクトは実際のファイル記述子を直接ラップしません(SSH内で発生する復号化や逆多重化などのため)。直接として使用するPopenのファイル記述子。

ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('echo test') 
proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE) 
while proc.poll() is not None: # (fixed) 
    buf = ssh_stdout.read(4096) 
    if not buf: 
     break 
    proc.stdin.write(buf) 

よう

何かがうまくいくかもしれません。つまり、SSH stdoutストリームを手動で最大4096バイトずつ読み取って、サブプロセスのstdinパイプに書き込みます。 リモートコマンドが終了したときに、上記のコードがどのように動作するかはわかりませんが、YMMVです。

+1

'proc.poll():'は本当に必要ではありませんが、_wrong_です。正常終了すると、0を返します。プログラム終了を積極的に待つためには、proc.poll()はNone:ではありません。 –

関連する問題