Wykonywanie poleceń przez ssh za pomocą Pythona

Piszę skrypt automatyzujący niektóre polecenia wiersza poleceń w Pythonie. W tej chwili robię połączenia tak:

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

Jednak muszę uruchomić kilka poleceń na zdalnej maszynie. Ręcznie, chciałbym zalogować się za pomocą ssh, a następnie uruchomić polecenia. Jak zautomatyzować to w Pythonie? Muszę się zalogować za pomocą (znanego) hasła do zdalnej maszyny, więc nie mogę po prostu użyć cmd = ssh user@remotehost, zastanawiam się, czy jest jakiś moduł, którego powinienem używać?

 93
Author: fredley, 2010-08-27

7 answers

Odsyłam do

Zobacz to pytanie

ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd_to_execute)
 136
Author: shahjapan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:24

Lub możesz po prostu użyć poleceń.getstatusoutput :

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

Używałem go intensywnie i działa świetnie.

W Pythonie 2.6+, użyj subprocess.check_output.

 37
Author: powerrox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-04 08:17:56

Czy widziałeś tkaniny ? Pozwala na wykonywanie wszelkiego rodzaju zdalnych rzeczy przez SSH przy użyciu Pythona.

 24
Author: supersighs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-23 19:49:40

Uznałem, że paramiko jest trochę za niskopoziomowe, a Fabric nie nadaje się specjalnie do wykorzystania jako biblioteka, więc stworzyłem własną bibliotekę o nazwie spur , która używa paramiko do implementacji nieco ładniejszego interfejsu:

import spur

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

Jeśli trzeba uruchomić wewnątrz powłoki:

shell.run(["sh", "-c", "echo -n hello"])
 13
Author: Michael Williamson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-10 21:37:06

Wszyscy już stwierdzili (zalecane) Użycie paramiko i właśnie udostępniam kod Pythona (można powiedzieć API), który pozwoli Ci wykonać wiele poleceń za jednym zamachem.

Aby wykonywać polecenia na różnych węzłach użyj : Commands().run_cmd(host_ip, list_of_commands)

Zobaczysz jedno TODO, które zatrzymałem, aby zatrzymać wykonywanie, jeśli któreś z poleceń nie wykona, Nie wiem, jak to zrobić. podziel się swoją wiedzą

#!/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 __name__ == "__main__":
    main(sys.argv[1:])
Dziękuję!
 5
Author: IAmSurajBobade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-27 09:42:52

Użyłem paramiko kilka (ładne) i pxssh (również ładne). Polecam. Działają nieco inaczej, ale mają stosunkowo duże nakładanie się w użyciu.

 3
Author: Eric Snow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-27 17:25:11

Przyjrzyjmy się spurplus, owijce, którą stworzyliśmy wokół spur, która zawiera adnotacje o typach i kilka drobnych sztuczek (ponowne łączenie SFTP, md5 itd.): https://pypi.org/project/spurplus/

 0
Author: marko.ristin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-16 03:28:53