python - libreria - ¿Cómo se ejecutan varios comandos en una sola sesión en Paramiko?(Pitón)
pip paramiko (5)
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 todavía tengo 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 tengo que hacerlo en llamadas a funciones separadas.
Estrictamente hablando, no puedes. De acuerdo con la especificación ssh:
Una sesión es una ejecución remota de un programa. El programa puede ser un shell, una aplicación, un comando del sistema o algún subsistema incorporado.
Esto significa que, una vez que se ejecuta el comando, la sesión finaliza. No puede ejecutar múltiples comandos en una sesión. Lo que PUEDE hacer, sin embargo, es iniciar un shell remoto (== un comando), e interactuar con ese shell a través de stdin, etc ... (piense en ejecutar un script de python frente a ejecutar el intérprete interactivo)
Intenta crear una cadena de comando separada por /n
personaje. Funcionó para mí Por. por ejemplo, ssh.exec_command("command_1 /n command_2 /n command_3")
Puede hacerlo invocando shell en el cliente y enviando comandos. Por favor refiérase here
La página tiene código para Python 3.5. He modificado un poco el código para trabajar con pythin 2.7. Agregar 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()
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 ayudará ... Yo personalmente usaría pexpect
o exscript
para las sesiones interactivas.
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()