Saltar al contenido

Comandos ssh de ejecución prolongada en el módulo python paramiko (y cómo finalizarlos)

No dejes de divulgar nuestra página y códigos en tus redes, ayúdanos a ampliar esta comunidad.

Solución:

En lugar de llamar a exec_command en el cliente, obtenga el transporte y genere su propio canal. El canal se puede usar para ejecutar un comando, y puede usarlo en una declaración de selección para averiguar cuándo se pueden leer los datos:

#!/usr/bin/env python
import paramiko
import select
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('host.example.com')
transport = client.get_transport()
channel = transport.open_session()
channel.exec_command("tail -f /var/log/everything/current")
while True:
  rl, wl, xl = select.select([channel],[],[],0.0)
  if len(rl) > 0:
      # Must be stdout
      print channel.recv(1024)

El objeto del canal se puede leer y escribir, conectándose con stdout y stdin del comando remoto. Puede ponerse en contacto con stderr llamando channel.makefile_stderr(...).

He configurado el tiempo de espera para 0.0 segundos porque se solicitó una solución sin bloqueo. Dependiendo de sus necesidades, es posible que desee bloquear con un tiempo de espera distinto de cero.

1) Puede cerrar el cliente si lo desea. El servidor en el otro extremo eliminará el proceso de cola.

2) Si necesita hacer esto sin bloqueo, tendrá que usar el objeto de canal directamente. Luego puede ver tanto stdout como stderr con channel.recv_ready() y channel.recv_stderr_ready(), o usar select.select.

Solo una pequeña actualización de la solución por Andrew Aylett. El siguiente código en realidad rompe el bucle y se cierra cuando finaliza el proceso externo:

import paramiko
import select

client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('host.example.com')
channel = client.get_transport().open_session()
channel.exec_command("tail -f /var/log/everything/current")
while True:
    if channel.exit_status_ready():
        break
    rl, wl, xl = select.select([channel], [], [], 0.0)
    if len(rl) > 0:
        print channel.recv(1024)

Tienes la opción de añadir valor a nuestra información aportando tu experiencia en las críticas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *