2016-04-08 8 views
5

Я намереваюсь запускать несколько команд на удаленном хостинге с помощью paramiko, но сеанс ssh закрывается после запуска команды.
Код перечислены ниже:Как сохранить сессию ssh не истек с помощью paramiko?

from paramiko import SSHClient 
import paramiko 
ssh = SSHClient() 
ssh.load_system_host_keys() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect(host, 22, user, passwd, timeout=3) 
stdin, stdout, stderr = ssh.exec_command('uname -a') 

Так есть ли способ остановить SSH сессию закрытия? Или любые альтернативы парамико?

Update:
Я был в состоянии держать вызов exec_command на моем Macbook при подключении к серверу Linux, но SSH сессия закрывается автоматически после того, как exec_command один раз на сервере Linux при подключении к переключателю и подняла ставку
SSHException: paramiko.ssh_exception.SSHException: SSH session not active

>>> print ssh.get_transport() 
>>> <paramiko.Transport at 0xf00216d0L (unconnected)> 
>>> print ssh.get_transport().is_active() 
>>> False 
>>> print ssh.get_transport().is_authenticated() 
>>> False 

есть ли способ сохранить paramiko сеанс SSH активен все время?

paramiko отладочная информация режим возвращается следующим образом:

начиная нить (режим клиента): 0x2657e10L
Connected (версия 1.99, клиент Comware-5.20)
Kex Algos: [u'diffie-Хеллмана -group-exchange-sha1 ', u'diffie-hellman- group14-sha1', u'diffie-hellman-group1-sha1 '] ключ сервера: [u'ssh-rsa'] клиент шифрует: [u'aes128-cbc ', u'3des-cbc', u'des-cbc '] server encrypt: [u'aes128-cbc', u'3des-cbc ', u'des-cbc'] клиент mac: [u'hmac-sha1 ', u'hmac-sha1-96', u'hmac-md5 ', u'hmac-md5-96'] сервер mac: [u'hmac-sha1 ', u'hmac-sha1-96', u'hmac -md5 ', u'hmac-md5-96'] клиентский компресс: [u'none '] сжимать сервер: [ u'none '] client lang: [u' '] server lang: [u' '] kex следует? False
Шифры согласованы: local = aes128-cbc, remote = aes128-cbc
Использование kex diffie-hellman-group14 -sha1; тип ключа сервера ssh-rsa; шифр: локальный aes128-cbc, удаленный aes128-cbc; mac: локальный hmac-sha1, удаленный hmac-sha1; компрессия: местный нет, удаленный нет
Переключиться на новые ключи ...
userauth в порядке
Аутентификация (пароль) успешно!
[чан 0] Макс пакета в: 32768 байтов
[чан 1] Макс пакета в: 32768 байтов
[чан 0] Макс пакетов из: 32496 байтов
Secsh канал 0 открыт.
Secsh канал 2 Не удалось открыть:
дефицит ресурсов: нехватка ресурсов
[чан 0] канал СЭЩ 0 запрос нормально
[чан 0] EOF послал (0)

+0

Есть ли еще сценарий, чем этот? Вы должны иметь возможность продолжать вызов 'exec_command'. – tdelaney

+0

Привет? Вы выполняете несколько команд в скрипте или запускаете несколько скриптов с одной командой? – tdelaney

+0

Мне удалось сохранить вызов 'exec_command' на моем Macbook, но он не работал на сервере Linux и поднял' SSHException: paramiko.ssh_exception.SSHException: сеанс SSH неактивен. Версия Python на Mac - 2,7.11, но на Сервер Linux - 2.6.6. @tdelaney –

ответ

1

Я вижу, что вы используете timeout параметр в вашу связную вызова:

ssh.connect(host, 22, user, passwd, timeout=3) 

Из документации:

тайм-аут (с плавающей точкой) - дополнительный тайм-аут (в секундах) для TCP подключения

В одном из моих сценариев я просто сделать:

ssh = paramiko.SSHClient() 
ssh.connect(host, username=settings.user) 

который держит соединение открытым, пока я не позову

ssh.close() 
+0

Тот же результат при подключении к ** переключателю ** с сервера Linux, но он отлично работал при подключении к Linux от другого. Кажется, не отличается ли параметр 'timeout' или нет. @LarsVegas –

+0

Вы видели это [SO] (http://stackoverflow.com/questions/31477121/python-paramiko-ssh-exception-ssh-session-not-active)? – LarsVegas

+0

Это определенно решило проблему неактивной ssh-сессии, но когда я запускаю ее параллельно, канал продолжал висеть там после отправки первой команды. @LarsVegas –

1

Вы можете реализовать интерактивную оболочку с использованием paramiko, таким образом канал не будет закрыт после выполнения команды на удаленной оболочке.

import paramiko 
import re 


class ShellHandler: 

    def __init__(self, host, user, psw): 
     self.ssh = paramiko.SSHClient() 
     self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
     self.ssh.connect(host, username=user, password=psw, port=22) 

     channel = self.ssh.invoke_shell() 
     self.stdin = channel.makefile('wb') 
     self.stdout = channel.makefile('r') 

    def __del__(self): 
     self.ssh.close() 

    @staticmethod 
    def _print_exec_out(cmd, out_buf, err_buf, exit_status): 
     print('command executed: {}'.format(cmd)) 
     print('STDOUT:') 
     for line in out_buf: 
      print(line, end="") 
     print('end of STDOUT') 
     print('STDERR:') 
     for line in err_buf: 
      print(line, end="") 
     print('end of STDERR') 
     print('finished with exit status: {}'.format(exit_status)) 
     print('------------------------------------') 
     pass 

    def execute(self, cmd): 
     """ 

     :param cmd: the command to be executed on the remote computer 
     :examples: execute('ls') 
        execute('finger') 
        execute('cd folder_name') 
     """ 
     cmd = cmd.strip('\n') 
     self.stdin.write(cmd + '\n') 
     finish = 'end of stdOUT buffer. finished with exit status' 
     echo_cmd = 'echo {} $?'.format(finish) 
     self.stdin.write(echo_cmd + '\n') 
     shin = self.stdin 
     self.stdin.flush() 

     shout = [] 
     sherr = [] 
     exit_status = 0 
     for line in self.stdout: 
      if str(line).startswith(cmd) or str(line).startswith(echo_cmd): 
       # up for now filled with shell junk from stdin 
       shout = [] 
      elif str(line).startswith(finish): 
       # our finish command ends with the exit status 
       exit_status = int(str(line).rsplit(maxsplit=1)[1]) 
       if exit_status: 
        # stderr is combined with stdout. 
        # thus, swap sherr with shout in a case of failure. 
        sherr = shout 
        shout = [] 
       break 
      else: 
       # get rid of 'coloring and formatting' special characters 
       shout.append(re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]').sub('', line). 
          replace('\b', '').replace('\r', '')) 

     # first and last lines of shout/sherr contain a prompt 
     if shout and echo_cmd in shout[-1]: 
      shout.pop() 
     if shout and cmd in shout[0]: 
      shout.pop(0) 
     if sherr and echo_cmd in sherr[-1]: 
      sherr.pop() 
     if sherr and cmd in sherr[0]: 
      sherr.pop(0) 

     self._print_exec_out(cmd=cmd, out_buf=shout, err_buf=sherr, exit_status=exit_status) 
     return shin, shout, sherr 

 Смежные вопросы

  • Нет связанных вопросов^_^