2016-05-31 17 views
1

は、私は、コマンドを実行し、リモートホストにログインするために小さなラッパークラスを書かれている都合上、最後には、データを取得する:paramikoが散発的に例外を発生させるのはなぜですか?

def MySSHClient: 

    def connect(self, remoteHost, remotePort, userName, password): 
     self.__s = paramiko.SSHClient() 
     self.__s.load_system_host_keys() 
     self.__s.connect(remoteHost, remotePort, userName, password) 

    def exec_command(self, command): 
     bufsize = -1 
     chan = self.__s.get_transport().open_session() 
     chan.exec_command(command) 
     stdin = chan.makefile('wb', bufsize) 
     stdout = chan.makefile('r', bufsize) 
     stderr = chan.makefile_stderr('r', bufsize) 
     stdin.close() 
     exitcode = chan.recv_exit_status() 
     r = MySSHCommandResult(command, stdin, stdout, stderr, exitcode) 
     chan.close() 
     return r 

    def close(self): 
     self.__s.close() 

このコードは、元のparamikoのPython実装から構成されています。私はちょうど最後の5行を追加しました。

.... 

exitCode = 0 
s = None 
try: 
    .... 
    exitCode = 3 
    s = MySSHClient() 
    s.connect(host, port, login, password) 
    exitCode = 4 
    result = s.exec_command(myCommand) 
    exitCode = 5 
    if not result.isSuccess(): 
     raise Exception("Failed to execute command!") 
    result.dump() # for current debugging purposes 
    exitCode = 0 
except: 
    pass 

if s is not None: 
    s.close() 
sys.exit(exitCode) 

(これらスルー:クラスMySSHClientは、単純なPythonプログラム内で使用され

(FYI。MySSHCommandResultは、さらなる使用のために構成および格納中stdoutとstrerrはからすべてのデータを読み出します)あなたが見ることができるように、失敗時にエラー診断を少し許可するために、さまざまな終了コードが使用されています)。

これまでのところとても良いです。基本的にはうまくいきます。しかし、私は理解していないことは時々私のPythonプログラムは、このような追加の出力に含まを与えるということである。

Exception ignored in: <object repr() failed> 
Traceback (most recent call last): 
    File "/usr/local/lib/python3.5/dist-packages/paramiko/file.py", line 61, in __del__ 
    File "/usr/local/lib/python3.5/dist-packages/paramiko/file.py", line 79, in close 
    File "/usr/local/lib/python3.5/dist-packages/paramiko/file.py", line 88, in flush 
TypeError: 'NoneType' object is not callable 

すべてがすべての時間を正常に動作しますが、20〜約10%で:

Exception ignored in: <bound method BufferedFile.__del__ of <paramiko.ChannelFile from <paramiko.Channel 0 (closed) ->  <paramiko.Transport at 0x74300588 (unconnected)>>>> 
Traceback (most recent call last): 
    File "/usr/local/lib/python3.5/dist-packages/paramiko/file.py", line 61, in __del__ 
    File "/usr/local/lib/python3.5/dist-packages/paramiko/file.py", line 79, in close 
    File "/usr/local/lib/python3.5/dist-packages/paramiko/file.py", line 88, in flush 
TypeError: 'NoneType' object is not callable 

またはこのような

これらのエラーメッセージが表示される時間の%。プログラムの終了時にクリーンアップが失敗することがあるのはなぜですか?これらのエラーメッセージを回避するにはどうすればよいですか?

+0

どのバージョンのparamikoを使用しますか? –

+0

お世話になりました!私はかなり新しいUbuntu 16.04のインストールに取り組んでいます。不思議なparamiko 1.17.0がインストールされました。それにもかかわらず、paramiko - version 2.0.0の最新バージョンへのアップグレードは何も変更しませんでした。エラーメッセージの行番号も同じままです。私はpip3経由でアップグレードし、バージョン2.0.0でそれを無駄にテストしました。 –

+0

これはおそらくパラミコのバグでしょう。バグレポートを書くべきです。また、 'chan.makefile()'によって開かれたすべての "ファイル"が 'close()'であることを確認する必要があります。これだけでは問題は解決しない可能性がありますが、このバグがあってもデータが失われないようにします。 –

答えて

0

私はまったく同じ問題に遭遇しました(最初はあなたの質問を見つけられなかった、開かれた私、今削除された)。 sys.exitで終了しないと、エラーは表示されなくなります。私のケースでは、関数内でparamikoなどの呼び出しをラップしていたので、sys.exitは同じスコープで呼び出されません。あなたの場合、あなたはできる:

def my_func(host, port, login, password, myCommand) 
    exitCode = 0 
    s = None 
    try: 
     .... 
     exitCode = 3 
     s = MySSHClient() 
     s.connect(host, port, login, password) 
     exitCode = 4 
     result = s.exec_command(myCommand) 
     exitCode = 5 
     if not result.isSuccess(): 
      raise Exception("Failed to execute command!") 
     exitCode = 0 
    except: 
     pass 
    if s is not None: 
     s.close() 
    return exitCode 

exit_code = my_func(my_host, my_port, my_login, my_password, my_command) 
sys.exit(exit_code) 

それは動作するはずです!

+0

実験をありがとう!しかし、私は疑問に思っています。違いは何ですか? exit()が呼び出された場合、Paramicoのクリーンアップに何か問題があることを示唆していますか?これについてあなたの意見は何ですか? –

+0

問題の私の限られた理解は、ガベージコレクションの問題があるということです。 'sys.exit'は' finally'ブロック内の文が実行されるように例外を呼び出すことによって動作します。私の推測は内部オブジェクトはおそらく破棄される*時々*ガベージコレクタによって*前に*それはparamikoの 'finally'のどこかで呼び出されますが、関数から呼び出すときは、関数が戻るまでオブジェクトは存続しなければなりません。 –

+0

興味があればparamikoギブスで[ticket](https://github.com/paramiko/paramiko/issues/1078)を開いています。 –

関連する問題