J'écris un script pour automatiser certaines commandes de ligne de commande en Python. En ce moment, je fais les appels suivants:
cmd = "some unix command"
retcode = subprocess.call(cmd,Shell=True)
Cependant, j'ai besoin d'exécuter des commandes sur une machine distante. Je me connecterais manuellement à l’aide de ssh, puis jetterais les commandes. Comment pourrais-je automatiser cela en Python? Je dois me connecter avec un mot de passe (connu) à la machine distante. Je ne peux donc pas simplement utiliser cmd = ssh user@remotehost
. Je me demande s'il existe un module à utiliser?
Je vous renvoie à paramiko
voir cette question
ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd_to_execute)
Ou vous pouvez simplement utiliser commands.getstatusoutput :
commands.getstatusoutput("ssh machine 1 'your script'")
Je l'ai utilisé abondamment et cela fonctionne très bien.
Dans Python 2.6+, utilisez subprocess.check_output
.
Avez-vous jeté un œil à Tissu ? Il vous permet de faire toutes sortes de choses distantes sur SSH en utilisant python.
J'ai trouvé que paramiko était un peu trop bas et Fabric ne convenant pas vraiment à être utilisé comme bibliothèque. J'ai donc créé ma propre bibliothèque appelée spur qui utilise paramiko pour implémenter une interface légèrement plus agréable:
import spur
Shell = spur.SshShell(hostname="localhost", username="bob", password="password1")
result = Shell.run(["echo", "-n", "hello"])
print result.output # prints hello
Si vous devez exécuter à l'intérieur d'un shell:
Shell.run(["sh", "-c", "echo -n hello"])
Tous ont déjà déclaré (recommandé) d'utiliser paramiko et je ne fais que partager un code python (API, pourrait-on dire) qui vous permettra d'exécuter plusieurs commandes à la fois.
pour exécuter des commandes sur différents nœuds, utilisez: Commands().run_cmd(Host_ip, list_of_commands)
Vous verrez un TODO, que j'ai gardé pour arrêter l'exécution si l'une des commandes échoue, je ne sais pas comment le faire. s'il vous plaît partagez vos connaissances
#!/usr/bin/python
import os
import sys
import select
import paramiko
import time
class Commands:
def __init__(self, retry_time=0):
self.retry_time = retry_time
pass
def run_cmd(self, Host_ip, cmd_list):
i = 0
while True:
# print("Trying to connect to %s (%i/%i)" % (self.Host, i, self.retry_time))
try:
ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(Host_ip)
break
except paramiko.AuthenticationException:
print("Authentication failed when connecting to %s" % Host_ip)
sys.exit(1)
except:
print("Could not SSH to %s, waiting for it to start" % Host_ip)
i += 1
time.sleep(2)
# If we could not connect within time limit
if i >= self.retry_time:
print("Could not connect to %s. Giving up" % Host_ip)
sys.exit(1)
# After connection is successful
# Send the command
for command in cmd_list:
# print command
print "> " + command
# execute commands
stdin, stdout, stderr = ssh.exec_command(command)
# TODO() : if an error is thrown, stop further rules and revert back changes
# Wait for the command to terminate
while not stdout.channel.exit_status_ready():
# Only print data if there is data to read in the channel
if stdout.channel.recv_ready():
rl, wl, xl = select.select([ stdout.channel ], [ ], [ ], 0.0)
if len(rl) > 0:
tmp = stdout.channel.recv(1024)
output = tmp.decode()
print output
# Close SSH connection
ssh.close()
return
def main(args=None):
if args is None:
print "arguments expected"
else:
# args = {'<ip_address>', <list_of_commands>}
mytest = Commands()
mytest.run_cmd(Host_ip=args[0], cmd_list=args[1])
return
if __== "__main__":
main(sys.argv[1:])
Je vous remercie!
#Reading the Host,username,password,port from Excel file
import paramiko
import xlrd
ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
loc = ('/Users/harshgow/Documents/PYTHON_WORK/labcred.xlsx')
wo = xlrd.open_workbook(loc)
sheet = wo.sheet_by_index(0)
Host = sheet.cell_value(0,1)
Port = int(sheet.cell_value(3,1))
User = sheet.cell_value(1,1)
Pass = sheet.cell_value(2,1)
def details(Host,Port,User,Pass):
ssh.connect(Host, Port, User, Pass)
print('connected to ip ',Host)
stdin, stdout, stderr = ssh.exec_command("")
stdin.write('xcommand SystemUnit Boot Action: Restart\n')
print('success')
details(Host,Port,User,Pass)
importer paramiko
temps d'importation
ssh = paramiko.SSHClient ()
ssh.set_missing_Host_key_policy (paramiko.AutoAddPolicy ())
ssh.connect ('10 .106.104.24 ', port = 22, nom d'utilisateur =' admin ', mot de passe =' ')
temps.sommeil (5)
print ('connecté')
stdin, stdout, stderr = ssh.exec_command ("")
def execute ():
stdin.write('xcommand SystemUnit Boot Action: Restart\n')
print('success')
exécuter()
paramiko a finalement travaillé pour moi après avoir ajouté une ligne supplémentaire, qui est vraiment importante (ligne 3):
import paramiko
p = paramiko.SSHClient()
p.set_missing_Host_key_policy(paramiko.AutoAddPolicy()) # This script doesn't work for me unless this line is added!
p.connect("server", port=22, username="username", password="password")
stdin, stdout, stderr = p.exec_command("your command")
opt = stdout.readlines()
opt = "".join(opt)
print(opt)
Assurez-vous que le paquet paramiko est installé . Source originale de la solution: Source
Rester simple. Aucune bibliothèque requise.
import subprocess
subprocess.Popen("ssh {user}@{Host} {cmd}".format(user=user, Host=host, cmd='ls -l'), Shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
Regardez spurplus
, un wrapper que nous avons développé autour de spur
qui fournit des annotations de types et quelques astuces mineures (reconnexion de SFTP, md5 etc.): https://pypi.org/project/spurplus/