Pregunta ¿Cuál es la forma más simple de usar SSH Python?


¿Cómo puedo simplemente SSH a un servidor remoto desde un script local de Python (3.0), proporcionar un nombre de usuario / contraseña, ejecutar un comando e imprimir el resultado a la consola de Python?

Preferiría no utilizar ninguna biblioteca externa grande ni instalar nada en el servidor remoto.


76
2017-08-05 14:34


origen


Respuestas:


No lo he intentado, pero esto pysftp módulo podría ayudar, que a su vez utiliza paramiko. Creo que todo es del lado del cliente.

El comando interesante es probablemente .execute() que ejecuta un comando arbitrario en la máquina remota. (El módulo también presenta .get() y .put métodos que aluden más a su carácter FTP).

ACTUALIZAR:

He vuelto a escribir la respuesta después de que la publicación del blog a la que originalmente me había vinculado ya no está disponible. Algunos de los comentarios que hacen referencia a la versión anterior de esta respuesta ahora se verán raros.


38
2017-08-05 14:49



Puede codificarlo usted mismo usando Paramiko, como se sugirió anteriormente. Alternativamente, puedes mirar Fabric, una aplicación de Python para hacer todas las cosas que preguntas:

Fabric es una biblioteca de Python y   herramienta de línea de comando diseñada para   agilizar la implementación de aplicaciones o   realizar tareas de administración del sistema   a través del protocolo SSH. Proporciona   herramientas para ejecutar shell arbitrario   comandos (ya sea como un inicio de sesión normal   usuario, o vía sudo), cargando y   descargar archivos, y así sucesivamente.

Creo que esto se ajusta a tus necesidades. Tampoco es una biblioteca grande y no requiere instalación de servidor, aunque sí tiene dependencias en paramiko y pycrypt que requieren instalación en el cliente.

La aplicación solía ser aquí. Ahora se puede encontrar aquí.

* The official, canonical repository is git.fabfile.org
* The official Github mirror is GitHub/bitprophet/fabric

Hay varios artículos buenos sobre él, aunque debe tener cuidado porque ha cambiado en los últimos seis meses:

Implementando Django con tela

Herramientas del pirata informático moderno de Python: virtualenv, tela y pipa

Implementación simple y fácil con Fabric y Virtualenv


Más tarde: Fabric ya no requiere la instalación de paramiko:

$ pip install fabric
Downloading/unpacking fabric
  Downloading Fabric-1.4.2.tar.gz (182Kb): 182Kb downloaded
  Running setup.py egg_info for package fabric
    warning: no previously-included files matching '*' found under directory 'docs/_build'
    warning: no files found matching 'fabfile.py'
Downloading/unpacking ssh>=1.7.14 (from fabric)
  Downloading ssh-1.7.14.tar.gz (794Kb): 794Kb downloaded
  Running setup.py egg_info for package ssh
Downloading/unpacking pycrypto>=2.1,!=2.4 (from ssh>=1.7.14->fabric)
  Downloading pycrypto-2.6.tar.gz (443Kb): 443Kb downloaded
  Running setup.py egg_info for package pycrypto
Installing collected packages: fabric, ssh, pycrypto
  Running setup.py install for fabric
    warning: no previously-included files matching '*' found under directory 'docs/_build'
    warning: no files found matching 'fabfile.py'
    Installing fab script to /home/hbrown/.virtualenvs/fabric-test/bin
  Running setup.py install for ssh
  Running setup.py install for pycrypto
...
Successfully installed fabric ssh pycrypto
Cleaning up...

Sin embargo, esto es principalmente cosmético: ssh es una bifurcación de paramiko, el mantenedor de ambas bibliotecas es el mismo (Jeff Forcier, también autor de Fabric), y el mantenedor tiene planes para reunir a paramiko y ssh bajo el nombre paramiko. (Esta corrección a través de pbanka.)


60
2017-08-05 15:00



Si desea evitar módulos adicionales, puede usar el módulo de subproceso para ejecutar

ssh [host] [command]

y captura la salida.

Pruebe algo como:

process = subprocess.Popen("ssh example.com ls", shell=True,
    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output,stderr = process.communicate()
status = process.poll()
print output

Para tratar con nombres de usuario y contraseñas, puede usar un subproceso para interactuar con el proceso ssh, o puede instalar una clave pública en el servidor para evitar la solicitud de contraseña.


22
2017-08-05 15:05



he escrito Enlaces de Python para libssh2. Libssh2 es una biblioteca del lado del cliente que implementa el protocolo SSH2.

import socket
import libssh2

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('exmaple.com', 22))

session = libssh2.Session()
session.startup(sock)
session.userauth_password('john', '******')

channel = session.channel()
channel.execute('ls -l')

print channel.read(1024)

16
2018-02-28 12:51



Su definición de "más simple" es importante aquí: un código simple significa usar un módulo (aunque una "gran biblioteca externa" es una exageración).

Creo que el módulo más actualizado (desarrollado activamente) es paramiko. Viene con scripts de demostración en la descarga, y tiene documentación de API en línea detallada. También puedes probar PxSSH, que está contenido en pexpect. Hay una muestra corta junto con la documentación en el primer enlace.

De nuevo con respecto a la simplicidad, tenga en cuenta que una buena detección de errores siempre hará que su código parezca más complejo, pero debería poder reutilizar una gran cantidad de código de las secuencias de comandos de muestra y luego olvidarse de ello.


8
2017-08-05 14:44



Como hughdbrown, me gusta Fabric. Tenga en cuenta que, si bien implementa sus propias secuencias de comandos declarativas (para implementar y demás), también puede importarse como un módulo de Python y utilizarse en sus programas sin tener que escribir una secuencia de comandos Fabric.

Fabric tiene un nuevo mantenedor y está en proceso de reescritura; eso significa que la mayoría de los tutoriales que encontrará (actualmente) en la web no funcionarán con la versión actual. Además, Google todavía muestra la página de Fabric anterior como el primer resultado.

Para la documentación actualizada, puede verificar: http://docs.fabfile.org


6
2017-08-06 10:08



Encontré el paramiko demasiado bajo, y Fabric no era especialmente adecuado para ser utilizado como biblioteca, así que armé mi propia biblioteca llamada estimular que usa paramiko para implementar una interfaz un poco más agradable:

import spur

shell = spur.SshShell(hostname="localhost", username="bob", password="password1")
result = shell.run(["echo", "-n", "hello"])
print result.output # prints hello

También puede optar por imprimir la salida del programa mientras se está ejecutando, lo que es útil si desea ver el resultado de los comandos de ejecución prolongada antes de que finalice:

result = shell.run(["echo", "-n", "hello"], stdout=sys.stdout)

6
2018-01-10 21:47



Esto funcionó para mí

import subprocess
import sys
HOST="IP"
COMMAND="ifconfig"

def passwordless_ssh(HOST):
        ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],
                       shell=False,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE)
        result = ssh.stdout.readlines()
        if result == []:
                error = ssh.stderr.readlines()
                print >>sys.stderr, "ERROR: %s" % error
                return "error"
        else:
                return result

1
2017-12-22 08:51



Para beneficio de aquellos que llegan aquí buscando en Google Python ssh sample. La pregunta y la respuesta originales son casi una decodificación anterior ahora. Parece que el paramiko ha ganado un poco de funcionalidades (de acuerdo, lo admitiré, pura adivinación aquí, soy nuevo en Python) y puedes crear el cliente ssh directamente con paramiko.

import base64
import paramiko

client = paramiko.SSHClient()

client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('192.168.1.1', username='user', password='password')
stdin, stdout, stderr = client.exec_command('cat /proc/meminfo')
for line in stdout:
    print('... ' + line.strip('\n'))
client.close()

Este código fue adaptado de una demostración de https://github.com/paramiko/paramiko Esto funciona para mi.


1
2018-06-21 11:09