¿Cómo ejecutas múltiples comandos en una sola sesión en Paramiko? (Pitón)

def exec_command(self, command, bufsize=-1): #print "Executing Command: "+command chan = self._transport.open_session() chan.exec_command(command) stdin = chan.makefile('wb', bufsize) stdout = chan.makefile('rb', bufsize) stderr = chan.makefile_stderr('rb', bufsize) return stdin, stdout, stderr 

Al ejecutar un comando en paramiko, siempre restablece la sesión cuando ejecuta exec_command. Quiero poder ejecutar sudo o su y aún tener esos privilegios cuando ejecuto otro exec_command. Otro ejemplo sería intentar ejecutar exec_command (“cd /”) y luego ejecutar exec_command nuevamente y tenerlo en el directorio raíz. Sé que puedes hacer algo como exec_command (“cd /; ls -l”), pero necesito hacerlo en llamadas a funciones separadas.

Casos de uso no interactivo

Este es un ejemplo no interactivo … envía cd tmp , ls y luego exit .

 import sys sys.stderr = open('/dev/null') # Silence silly warnings from paramiko import paramiko as pm sys.stderr = sys.__stderr__ import os class AllowAllKeys(pm.MissingHostKeyPolicy): def missing_host_key(self, client, hostname, key): return HOST = '127.0.0.1' USER = '' PASSWORD = '' client = pm.SSHClient() client.load_system_host_keys() client.load_host_keys(os.path.expanduser('~/.ssh/known_hosts')) client.set_missing_host_key_policy(AllowAllKeys()) client.connect(HOST, username=USER, password=PASSWORD) channel = client.invoke_shell() stdin = channel.makefile('wb') stdout = channel.makefile('rb') stdin.write(''' cd tmp ls exit ''') print stdout.read() stdout.close() stdin.close() client.close() 

Casos de uso interactivo
Si tiene un caso de uso interactivo, esta respuesta no será de ayuda … Personalmente usaría pexpect o exscript para sesiones interactivas.

Estrictamente hablando, no puedes. Según la especificación ssh:

Una sesión es una ejecución remota de un progtwig. El progtwig puede ser un shell, una aplicación, un comando del sistema o algún subsistema incorporado.

Esto significa que, una vez que el comando se ha ejecutado, la sesión ha finalizado. No puede ejecutar varios comandos en una sesión. Sin embargo, lo que PUEDES hacer es iniciar un shell remoto (== un comando), e interactuar con ese shell a través de stdin, etc.

Intente crear una cadena de comandos separada por \n carácter. Funciono para mi Por. por ejemplo, ssh.exec_command("command_1 \n command_2 \n command_3")

 cmd = 'ls /home/dir' self.ssh_stdin, self.ssh_stdout, self.ssh_stderr = self.ssh.exec_command(cmd) print self.ssh_stdout.read() cmd2 = 'cat /home/dir/test.log' self.ssh_stdin2, self.ssh_stdout2, self.ssh_stderr2 = self.ssh.exec_command(cmd2) print self.ssh_stdout2.read() 

Puede hacerlo invocando shell en el cliente y enviando comandos. Por favor refiérase aquí
La página tiene código para python 3.5. He modificado un poco el código para que funcione con pythin 2.7. Agregando código aquí para referencia

 import threading, paramiko strdata='' fulldata='' class ssh: shell = None client = None transport = None def __init__(self, address, username, password): print("Connecting to server on ip", str(address) + ".") self.client = paramiko.client.SSHClient() self.client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy()) self.client.connect(address, username=username, password=password, look_for_keys=False) self.transport = paramiko.Transport((address, 22)) self.transport.connect(username=username, password=password) thread = threading.Thread(target=self.process) thread.daemon = True thread.start() def close_connection(self): if(self.client != None): self.client.close() self.transport.close() def open_shell(self): self.shell = self.client.invoke_shell() def send_shell(self, command): if(self.shell): self.shell.send(command + "\n") else: print("Shell not opened.") def process(self): global strdata, fulldata while True: # Print data when available if self.shell is not None and self.shell.recv_ready(): alldata = self.shell.recv(1024) while self.shell.recv_ready(): alldata += self.shell.recv(1024) strdata = strdata + str(alldata) fulldata = fulldata + str(alldata) strdata = self.print_lines(strdata) # print all received data except last line def print_lines(self, data): last_line = data if '\n' in data: lines = data.splitlines() for i in range(0, len(lines)-1): print(lines[i]) last_line = lines[len(lines) - 1] if data.endswith('\n'): print(last_line) last_line = '' return last_line sshUsername = "SSH USERNAME" sshPassword = "SSH PASSWORD" sshServer = "SSH SERVER ADDRESS" connection = ssh(sshServer, sshUsername, sshPassword) connection.open_shell() connection.send_shell('cmd1') connection.send_shell('cmd2') connection.send_shell('cmd3') time.sleep(10) print(strdata) # print the last line of received data print('==========================') print(fulldata) # This contains the complete data received. print('==========================') connection.close_connection()