Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么帕拉米科偶尔会提出一个例外?_Python_Ssh_Paramiko - Fatal编程技术网

Python 为什么帕拉米科偶尔会提出一个例外?

Python 为什么帕拉米科偶尔会提出一个例外?,python,ssh,paramiko,Python,Ssh,Paramiko,为了方便起见,我编写了一个小包装器类,用于登录远程主机、执行命令、最终检索数据: def MySSHClient: def connect(self, remoteHost, remotePort, userName, password): self.__s = paramiko.SSHClient() self.__s.load_system_host_keys() self.__s.connect(remoteHost, remote

为了方便起见,我编写了一个小包装器类,用于登录远程主机、执行命令、最终检索数据:

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()
此代码改编自原始的paramikopython实现。我刚刚加了最后5行

(仅供参考:myshCommandResult在构建过程中从stdout和strerr读取所有数据,并将其存储以供进一步使用。)

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

....

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程序告诉调用者一切是否成功。正如您所看到的,使用了各种退出代码,以便在失败时进行一些错误诊断。)

到目前为止还不错。基本上这是可行的。但我不明白的是,有时我的python程序会提供如下额外输出:

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
中忽略的异常:>
回溯(最近一次呼叫最后一次):
文件“/usr/local/lib/python3.5/dist-packages/paramiko/File.py”,第61行,在__
文件“/usr/local/lib/python3.5/dist-packages/paramiko/File.py”,第79行,关闭
文件“/usr/local/lib/python3.5/dist packages/paramiko/File.py”,第88行,刷新
TypeError:“非类型”对象不可调用
或者像这样:

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
中忽略的异常:
回溯(最近一次呼叫最后一次):
文件“/usr/local/lib/python3.5/dist-packages/paramiko/File.py”,第61行,在__
文件“/usr/local/lib/python3.5/dist-packages/paramiko/File.py”,第79行,关闭
文件“/usr/local/lib/python3.5/dist packages/paramiko/File.py”,第88行,刷新
TypeError:“非类型”对象不可调用

每件事都可以正常工作,但大约有10%到20%的时间我会看到这些错误消息。有人知道为什么有时候程序终止时清理会失败吗?如何避免这些错误消息?

我遇到了完全相同的问题(起初没有找到您的问题,打开了我的问题,现在已删除)。如果您没有使用
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)

它应该会起作用

我和你有同样的问题。当我使用
exec\u命令(command)
时,我发现在我的命令字符串末尾有一个
'\n'
。我删除了
“\n”
,它就可以工作了。如果使用
'\n'
将其分隔,则
exec\u命令可以执行一系列命令。因此,我认为最后一个
'\n'
启动了一个新对象,但它不在其中,因此导致none类型错误。

由于某些原因,当sys.exit时,垃圾不会自动清理

要手动强制执行cleapup,只需使用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
这是我的消息来源:

您使用的是哪种版本的paramiko?谢谢您的提问!我正在进行一个全新的Ubuntu 16.04安装。奇怪的是,安装了paramiko 1.17.0。尽管如此,升级到paramiko的最新版本(2.0.0版)并没有改变任何事情。甚至错误消息的行号也保持不变。我刚刚通过pip3升级,并用2.0.0版测试了它,但没有用。这很可能是paramiko的错误。你应该写一份bug报告。另外,您应该确保由
chan.makefile()
打开的每个“文件”都是
close()
d。虽然仅此一项不太可能解决问题,但它将确保在出现此错误时不会丢失任何数据。Hm。你真的认为这是一只虫子?考虑到可能有数以百万计的人在使用paramiko,我没有这样想。查看
paramiko/file.py
的第88行,唯一被调用的对象是
BytesIO
。唯一能“突然”变成
None
的方法是在解释器关闭时进行垃圾收集(除非有人明确地将其设置在某个地方,这是不可能的)。感谢您的尝试!但我想知道:这有什么区别?如果调用exit(),则表明清理Paramico有问题?你对此有什么看法?我对这个问题的有限理解是存在垃圾收集问题
sys.exit
的工作原理是引发异常,以便执行
finally
块中的语句。我的猜测是,在paramiko的
finally
中调用内部对象之前,垃圾收集器有时可能会破坏它,而从函数调用它时,该对象必须一直存在,直到函数返回。如果您感兴趣,我已经在paramiko github上打开了一个。哦,是的!谢谢没问题。如果您有机会尝试,请告诉我我的解决方案是否也解决了您的问题。