2016-05-11 6 views
3

Я хочу написать метод, который принимает IP, имя пользователя и пароль и возвращает открытое SFTP-соединение с этим сервером. Вот код, у меня есть, используя paramiko:paramiko: метод для открытия и возврата sftp conneciton

def open_sftp_connection(ip, user, passwd): 
    ssh = SSHClient() 
    ssh.load_system_host_keys() 
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    ssh.connect(ip, 22, user, passwd) 
    assert ssh.get_transport().is_active(), 'Failed to connect to server' 

    sftp = ssh.open_sftp() 
    return sftp 

Если я выполняю этот код непосредственно в оболочке Python, она отлично работает:

>>> ssh = SSHClient() 
>>> ssh.load_system_host_keys() 
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
>>> ssh.connect(ip, 22, user, passwd) 
>>> assert ssh.get_transport().is_active(), 'Failed to connect to server' 
>>> sftp = ssh.open_sftp() 
>>> print sftp.get_channel().get_transport().is_active() 
True 

Но когда я положил его в функцию и вызвать функцию соединение SFTP приходит обратно отсоединен:

>>> def open_sftp_connection(ip, user, passwd): 
...  ssh = SSHClient() 
...  ssh.load_system_host_keys() 
...  ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
...  ssh.connect(ip, 22, user, passwd) 
...  assert ssh.get_transport().is_active(), 'Failed to connect to server' 
...  sftp = ssh.open_sftp() 
...  return sftp 
... 
>>> sftp = open_sftp_connection(ip, user, passwd) 
>>> print sftp.get_channel().get_transport().is_active() 
False 

Единственное, что я могу думать, соединение SSH хранится локально в ssh, тогда, когда функция возвращает, ssh - сбор мусора, и соединение прекращается, поэтому, пока SFTPClient все еще существует, базовое соединение теперь мертво.

Если это так, как я могу его решить? Если нет, что на самом деле происходит?

EDIT: Я изменил функцию, чтобы вернуть sftp, ssh, и теперь соединение остается открытым. Так что это сборщик мусора, который является виновником. Можно ли это решить, не возвращая два значения?

+0

Если вы подозреваете, что GC является виновником, попробуйте вернуть 'ssh, sftp' и посмотреть, поддерживает ли это его жизнь. – user590028

ответ

2

Вам необходим доступ к экземплярам ssh и sftp.

def open_sftp_connection(ip, user, passwd): 
    ssh = SSHClient() 
    ssh.load_system_host_keys() 
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    ssh.connect(ip, 22, user, passwd) 
    assert ssh.get_transport().is_active(), 'Failed to connect to server' 
    return ssh, ssh.open_sftp() 

ssh, sftp = open_sftp_connection(ip, user, passwd) 
print sftp.get_channel().get_transport().is_active() 
+0

можно ли это выполнить без фактического возврата двух значений? – ewok

+0

да, но вам нужно будет открыть sftp-соединение за пределами функции ... ssh = open_sftp_connection (ip, user, passwd) sftp = ssh.open_sftp() – Craneum

+0

так что требование одной функции, которая принимает ip, пользователя и пароля, и возвращается только открытое соединение sftp невозможно? – ewok