Realizar comandos a través de ssh con Python
Estoy escribiendo un script para automatizar algunos comandos de la línea de comandos en Python. Por el momento estoy haciendo llamadas como esta:
cmd = "some unix command"
retcode = subprocess.call(cmd,shell=True)
Sin embargo, necesito ejecutar algunos comandos en una máquina remota. Manualmente, iniciaría sesión usando ssh
y luego ejecutaría los comandos. ¿Cómo automatizaría esto en Python? Necesito iniciar sesión con una contraseña (conocida) en la máquina remota, por lo que no puedo simplemente usar cmd = ssh user@remotehost
. Me pregunto si hay algún módulo que debería usar.
Te recomendaré a paramiko.
ver esta pregunta
ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd_to_execute)
Si está utilizando claves ssh, haga:
k = paramiko.RSAKey.from_private_key_file(keyfilename)
# OR k = paramiko.DSSKey.from_private_key_file(keyfilename)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=host, username=user, pkey=k)
Mantenlo simple. No se requieren bibliotecas.
import subprocess
# Python 2
subprocess.Popen("ssh {user}@{host} {cmd}".format(user=user, host=host, cmd='ls -l'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
# Python 3
subprocess.Popen(f"ssh {user}@{host} {cmd}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
O simplemente puedes usar comandos.getstatusoutput :
commands.getstatusoutput("ssh machine 1 'your script'")
Lo usé mucho y funciona muy bien.
En Python 2.6+, use subprocess.check_output
.
Encontré que paramiko tiene un nivel demasiado bajo y Fabric no es especialmente adecuado para ser usado como biblioteca, así que armé mi propia biblioteca llamada spur que usa paramiko para implementar una interfaz ligeramente mejor:
import spur
shell = spur.SshShell(hostname="localhost", username="bob", password="password1")
result = shell.run(["echo", "-n", "hello"])
print result.output # prints hello
Si necesita ejecutar dentro de un shell:
shell.run(["sh", "-c", "echo -n hello"])