How to keep ssh session not expired using paramiko?

I intend to run several commands on the remote host using paramiko, but the ssh session is closed after running the command.
Code below:

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') 

So, is there a way to stop the ssh session from closing? Or any alternatives to paramiko?

Update :
I was able to support the exec_command call on my Macbook when connected to a Linux server, but the ssh session was automatically closed after exec_command once on the Linux server when connected to the switch and 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 

Is there a way to keep paramiko ssh session active all the time?

Paramiko debug mode information is returned as follows:

initial stream (client mode): 0x2657e10L
Connected (version 1.99, Comware-5.20 client)
kex algos: [u'diffie-hellman-group-exchange-sha1 ', u'diffie-hellman-group14-sha1', u'diffie-hellman-group1-sha1 '] server key: [u'ssh-rsa'] the client encrypts: [u'aes128-cbc ', u'3des-cbc', u'des-cbc '] the server encrypts: [u'aes128-cbc', u'3des-cbc ', u'des-cbc'] mac client: [u'hmac-sha1 ', u'hmac-sha1-96', u'hmac-md5 ', u'hmac-md5-96'] mac server: [u'hmac-sha1 ', u'hmac -sha1-96 ', u'hmac-md5', u'hmac-md5-96 '] client compress: [u'none'] server compress: [u'none '] client lang: [u' '] server lang : [u ''] kex follows? False
Ciphers agreed: local = aes128-cbc, remote = aes128-cbc
using kex diffie-hellman-group14-sha1; ssh-rsa server key type cipher: local aes128-cbc, remote aes128-cbc; mac: local hmac-sha1, remote hmac-sha1; compression: local no, remote no
Switch to new keys ...
userauth ok
Authentication (password) is successful!
[chan 0] Maximum packet in: 32768 bytes
[chan 1] Maximum packet in: 32768 bytes
[chan 0] Maximum packet: 32496 bytes
Secsh channel is open.
Secsh channel 2 is open FAILED:
Lack of resources: lack of resources
[chan 0] Sesch channel 0 request ok
[chan 0] EOF sent (0)

+5
source share
2 answers

I see that you are using the timeout parameter in your connection call:

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

From the documentation:

timeout (float) - additional timeout (in seconds) for TCP connection

In one of my scripts, I just do:

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

which keeps the connection open until I call

 ssh.close() 
+1
source

You can implement an interactive shell using paramiko, so the channel will not be closed after executing the command on the remote shell.

 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 
+1
source

Source: https://habr.com/ru/post/1246669/


All Articles