web-dev-qa-db-ja.com

Python paramikoスクリプト、exec_command()中に出力を読み取る際の問題

背景:pythonとparamikoを使用して、クラスのプログラムを提出する必要があるたびに実行するプロセスを自動化します。「handin」というコマンドを使用します。 「ソースコードを送信するには、ただしこれは学校のコンピューターから実行する必要があります。したがって、自宅からコードを送信するときは、次のことを行う必要があります。学校のサーバーにsftpを送信し、ファイルをディレクトリに配置し、学校のコンピューターにsshを送信し、「handin」コマンドを使用します。

学校のマシンにファイルを正常に配置できます。この問題は、exec_command( 'handin my files')を使用してから、出力を読み取って次のアクションを決定しようとすると発生します。

ので、私は持っています

try:
   (stdin, stdout, stderr) = client.exec_command(s)
except:
   print 'whoops'
   sys.exit()
print stdout.readlines()

しかし、これは何らかの理由でデッドロックを引き起こし、スクリプトは何もしていないように見え、最終的にプロセス全体を強制終了する必要があります(ctrl + cは機能しません)。 exec_commandが正しく完了していないか(try/catchブロックから出ている場合でも)、ネットワークに問題があるかどうかはわかりません。

何か案は?

更新:

問題は、実行中にhandinコマンドを操作することです。コマンドの実行後、handinがまだ実行されている場合と実行されていない場合があります。初めて送信する場合は、成功、何とか何とかと言って、実行を終了します。すべては順調です。ただし、再送信する場合は、各ファイルの上書き(stdin.write( 'y'))を承認する必要があります。

TL/DR:

Exec_command()がまだ実行されているかどうか、入力を待っているかどうか、それに応じてstdoutからのreadline()を確認するにはどうすればよいですか?

11
macgregor

上記のコードスニピットに問題はありません。以下のプログラムは、ホストにログインし、lsコマンドを実行してファイルを表示する完全なスクリプトです。私はそれを試したところ、それは私のために働きます。おそらくこれを試して、それがあなたのために働くかどうか確かめてください。それが機能しない場合は、sshサーバー、実行中のコマンド、またはparamikoのインストールのいずれかに固有の問題があると思われます。それがあなたのために働くならば、それはあなたの既存の機能に向かって移動してそれがどこで壊れているかを見るためにこれに変更を加えるだけの問題です。

import paramiko
ssh=paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('<ip address here>',username='<username here>',password='<password here>')
stdin,stdout,stderr = ssh.exec_command("ls /")
print stdout.readlines()

それがうまくいく場合、私の次の提案は、「ls /」を実行しようとしている実際のhandinコマンドに置き換えてみることです。コマンドがユーザー入力などを待ってハングしている可能性があります。

12
bdk

問題は、リモートコマンドが入力を待機していることである可能性があります(指示がない限り、行かないことを知らずに、stdinに何かを書き込むことを期待しています)。 stdin.channel.shutdown_write()を試してください(stdin.close()だけではうまくいかないと思います。フラッシュが発生するだけです)

6
Steven

これは古いスレッドですが、私もこの問題を見てきました。これは、リモートコマンドから大きなSTDOUTを処理できないため、ハングするParamikoのバグが原因です。

参照: https://github.com/paramiko/paramiko/issues/515

考えられる解決策: https://Gist.github.com/matjohn2/2c1c4988e17112a34f310667e0ff6e7e

0

これを回避してIfconfigの出力を取得するには、オプションを使用してみてください。 get_pty = True

例えば:

import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())

def MonitorProcess():
    ssh.connect('10.2.0.230', username='ibmsys1', password='passw0rd', timeout=5)
    stdin, stdout, stderr = ssh.exec_command('/sbin/ifconfig', timeout=3, get_pty=True)
    #stdin, stdout, stderr = ssh.exec_command('/sbin/ifconfig') -> simple exec ex.
    print stdout.read()

MonitorProcess()
0
Krayher