it-swarm.com.de

Befehle über ssh mit Python ausführen

Ich schreibe ein Skript, um einige Befehlszeilenbefehle in Python zu automatisieren. Im Moment mache ich Anrufe so:

cmd = "some unix command"
retcode = subprocess.call(cmd,Shell=True)

Ich muss jedoch einige Befehle auf einem Remote-Computer ausführen. Manuell habe ich mich mit ssh angemeldet und dann die Befehle ausgeführt. Wie würde ich dies in Python automatisieren? Ich muss mich mit einem (bekannten) Kennwort an der Remote-Maschine anmelden, sodass ich nicht einfach cmd = ssh [email protected] verwenden kann. Ich frage mich, ob es ein Modul gibt, das ich verwenden sollte?

99
fredley

Ich beziehe mich auf paramiko

siehe diese Frage

ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd_to_execute)
151
shahjapan

Oder Sie verwenden einfach command.getstatusoutput :

   commands.getstatusoutput("ssh machine 1 'your script'")

Ich habe es ausgiebig benutzt und es funktioniert großartig.

Verwenden Sie in Python 2.6+ subprocess.check_output .

41
powerrox

Haben Sie einen Blick auf Stoff geworfen? Es erlaubt Ihnen, alle Arten von Remote-Sachen über SSH mit Python auszuführen.

25
supersighs

Ich fand, dass Paramiko etwas zu niedrig ist, und Fabric ist nicht besonders gut geeignet, um als Bibliothek verwendet zu werden. Deshalb habe ich meine eigene Bibliothek namens spur zusammengestellt, die mit paramiko eine etwas schönere Schnittstelle implementiert:

import spur

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

Wenn Sie in einer Shell laufen müssen:

Shell.run(["sh", "-c", "echo -n hello"])
14

Alle haben bereits (empfohlen) mit paramiko angegeben, und ich teile gerade einen Python-Code (API kann man sagen), der es Ihnen ermöglicht, mehrere Befehle gleichzeitig auszuführen.

um Befehle auf verschiedenen Knoten auszuführen, verwenden Sie: Commands().run_cmd(Host_ip, list_of_commands)

Sie werden einen TODO sehen, den ich immer gehalten habe, um die Ausführung zu stoppen, wenn einer der Befehle nicht ausgeführt wird. Ich weiß nicht, wie er ausgeführt werden soll. Bitte teile dein Wissen

#!/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:])

Vielen Dank!

5
IAmSurajBobade

Ich habe paramiko ein Bündel (Nice) und pxssh (auch Nice) verwendet. Ich würde entweder empfehlen. Sie arbeiten etwas anders, haben aber eine relativ große Überlappung.

4
Eric Snow
#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)
1
Harshan Gowda

Funktioniert perfekt...

paramiko importieren

importzeit

ssh = paramiko.SSHClient ()

ssh.load_system_Host_keys ()

ssh.set_missing_Host_key_policy (paramiko.AutoAddPolicy ())

ssh.connect ('10 .106.104.24 ', port = 22, username =' admin ', password =' ​​')

schlafenszeit (5)

drucken ('verbunden')

stdin, stdout, stderr = ssh.exec_command ("")

def execute ():

   stdin.write('xcommand SystemUnit Boot Action: Restart\n')

   print('success')

ausführen()

0
Harshan Gowda

paramiko arbeitete endlich für mich nach dem Hinzufügen einer zusätzlichen Zeile, was wirklich wichtig ist (Zeile 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)

Stellen Sie sicher, dass das paramiko-Paket installiert ist . Ursprüngliche Quelle der Lösung: Source

0

Halte es einfach. Keine Bibliotheken erforderlich.

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()
0
Ronn Macc

Werfen Sie einen Blick auf spurplus, einen von spur entwickelten Wrapper, der Typanmerkungen und einige kleinere Tricks enthält (SFTP verbinden, md5 etc.): Https://pypi.org/project/spurplus/

0
marko.ristin