为什么 paramiko 偶尔会引发异常? [英] Why does paramiko sporadically raise an exception?

查看:209
本文介绍了为什么 paramiko 偶尔会引发异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了方便,我编写了一个小的包装类来登录远程主机,执行命令,结束检索数据:

For convenience I have written a small wrapper class to login on a remote host, execute a command, end retrieve the data:

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 行.

This code is adapted from the original paramiko python implementation. I just added the last 5 lines.

(仅供参考:MySSHCommandResult 在构建期间从 stdout 和 strerr 读取所有数据并将其存储以供进一步使用.)

(FYI: MySSHCommandResult reads all data from stdout and strerr during construction and stores it for further use.)

MySSHClient 类在一个简单的 Python 程序中使用:

The class MySSHClient is used within a simple python program:

....

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)

(python 程序通过这些退出代码告诉调用者一切是否成功.如您所见,使用了各种退出代码以允许对失败进行一些错误诊断.)

(Through these exit codes the python program tells the caller if everything succeeded. As you can see a variety of exit codes is used in order to allow a bit of error diagnosis on failure.)

到目前为止一切顺利.基本上这是有效的.但我不明白的是,有时我的 python 程序会给出这样的额外输出:

So far so good. Basically this works. But what I do not understand is that sometimes my python program gives additional ouput like this:

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

或者像这样:

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

一切正常,但大约有 10% 到 20% 的时间我会看到这些错误消息.有谁知道为什么有时清理会在程序终止时失败?如何避免这些错误消息?

Everything works fine all the time, but at about 10% to 20% of the time I see these error messages. Has anyone an idea why sometimes the cleanup fails on program termination? How can I avoid these error messages?

推荐答案

由于某些原因,sys.exit时没有自动清理垃圾

For some reason, the garbage is not cleaned up automatically when sys.exit

要手动强制 cleapup,您可以简单地使用 del 删除分配的对象.

To force the cleapup manually you can simply delete your allocated objected with del.

这是我的代码:

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, port, username, password)
stdin_raw, stdout_raw, stderr_raw = client.exec_command(cmd)
exit_code = stdout_raw.channel.recv_exit_status() 

stdout = []
for line in stdout_raw:
    stdout.append(line.strip())

stderr = []
for line in stderr_raw:
    stderr.append(line.strip())


# Clean up elements
client.close()
del client, stdin_raw, stdout_raw, stderr_raw


logger.debug("stdout: %s" % stdout)
logger.debug("stderr: %s" % stderr)
logger.debug("exit_code: %s" % exit_code)

请注意:

del client, stdin_raw, stdout_raw, stderr_raw

这是我的来源:https://github.com/paramiko/paramiko/issues/1078#issuecomment-596771584

这篇关于为什么 paramiko 偶尔会引发异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆