Выполнять команды через SSH с Python - PullRequest
106 голосов
/ 27 августа 2010

Я пишу скрипт для автоматизации некоторых команд командной строки в Python.На данный момент я делаю вызовы так:

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

Однако мне нужно выполнить некоторые команды на удаленном компьютере.Вручную, я бы войти в систему с помощью ssh, а затем запустить команды.Как бы я автоматизировал это в Python?Мне нужно войти с (известным) паролем на удаленный компьютер, поэтому я не могу просто использовать cmd = ssh user@remotehost, мне интересно, есть ли модуль, который я должен использовать?

Ответы [ 12 ]

161 голосов
/ 27 августа 2010

Я отсылаю вас к paramiko

см. этот вопрос

ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd_to_execute)
43 голосов
/ 27 августа 2010

Или вы можете просто использовать commands.getstatusoutput :

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

Я широко использовал его, и он прекрасно работает.

В Python 2.6+ используйте subprocess.check_output.

27 голосов
/ 27 августа 2010

Вы смотрели на Ткань ?Это позволяет вам делать всякие удаленные вещи через SSH, используя python.

15 голосов
/ 11 января 2013

Я обнаружил, что paramiko слишком низкоуровневый, и Fabric не особенно подходит для использования в качестве библиотеки, поэтому я собрал свою собственную библиотеку под названием spur , которая использует paramiko для реализациинемного более приятный интерфейс:

import spur

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

Если вам нужно запустить внутри оболочки:

shell.run(["sh", "-c", "echo -n hello"])
6 голосов
/ 28 марта 2017

Все уже заявили (рекомендуется), используя paramiko , и я просто делюсь кодом Python (можно сказать, API), который позволит вам выполнять несколько команд за один раз.

для выполнения команд на другом узле используйте: Commands().run_cmd(host_ip, list_of_commands)

Вы увидите один TODO, который я сохранил, чтобы остановить выполнение, если какая-либо из команд не будет выполнена, я не знаю, как это сделатьсделай это.Пожалуйста, поделитесь своими знаниями

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

Спасибо!

4 голосов
/ 27 августа 2010

Я использовал paramiko связку (приятно) и pxssh (тоже приятно). Я бы порекомендовал либо. Они работают немного по-другому, но имеют относительно большое совпадение в использовании.

0 голосов
/ 14 мая 2019

Запрос пользователя ввести команду в соответствии с устройством, в которое он входит.
Приведенный ниже код подтвержден PEP8online.com.

import paramiko
import xlrd
import time

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):
    time.sleep(2)
    ssh.connect(Host, Port, User, Pass)
    print('connected to ip ', Host)
    stdin, stdout, stderr = ssh.exec_command("")
    x = input('Enter the command:')
    stdin.write(x)
    stdin.write('\n')
    print('success')

details(Host, Port, User, Pass)
0 голосов
/ 14 мая 2019
#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)
0 голосов
/ 13 мая 2019

Ниже приведен пример, если вы хотите, чтобы пользователь вводил имя хоста, имя пользователя, пароль и номер порта.

  import paramiko

  ssh = paramiko.SSHClient()

  ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())



  def details():

  Host = input("Enter the Hostname: ")

  Port = input("Enter the Port: ")

  User = input("Enter the Username: ")

  Pass = input("Enter the Password: ")

  ssh.connect(Host, Port, User, Pass, timeout=2)

  print('connected')

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

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

  print('success')

  details()
0 голосов
/ 11 мая 2019

Работает отлично ...

import paramiko
import time

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='')

time.sleep(5)
print('connected')
stdin, stdout, stderr = ssh.exec_command(" ")

def execute():
       stdin.write('xcommand SystemUnit Boot Action: Restart\n')
       print('success')

execute()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...