Ik ben een script aan het schrijven om enkele commandoregelcommando’s in Python te automatiseren. Op dit moment bel ik als volgt:
cmd = "some unix command"
retcode = subprocess.call(cmd,shell=True)
Ik moet echter enkele opdrachten uitvoeren op een externe computer. Handmatig zou ik inloggen met ssh en vervolgens de opdrachten uitvoeren. Hoe zou ik dit automatiseren in Python? Ik moet inloggen met een (bekend) wachtwoord op de externe machine, dus ik kan niet zomaar cmd = ssh user@remotehost
gebruiken. Ik vraag me af of er een module is die ik zou moeten gebruiken?
Antwoord 1, autoriteit 100%
Ik verwijs je naar paramiko
zie deze vraag
ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd_to_execute)
Als je ssh-sleutels gebruikt, doe dan:
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)
Antwoord 2, autoriteit 22%
Of je kunt gewoon commands.getstatusoutput:
commands.getstatusoutput("ssh machine 1 'your script'")
Ik heb het veel gebruikt en het werkt geweldig.
Gebruik in Python 2.6+ subprocess.check_output
.
Antwoord 3, autoriteit 17%
Houd het simpel. Geen bibliotheken vereist.
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()
Antwoord 4, autoriteit 9%
Ik vond paramiko een beetje te laag niveau en Fabric niet bijzonder geschikt om als bibliotheek te worden gebruikt, dus heb ik mijn eigen bibliotheek samengesteld met de naam spurdie paramiko gebruikt om een iets mooiere interface te implementeren:
import spur
shell = spur.SshShell(hostname="localhost", username="bob", password="password1")
result = shell.run(["echo", "-n", "hello"])
print result.output # prints hello
Als je binnen een shell moet rennen:
shell.run(["sh", "-c", "echo -n hello"])
Antwoord 5, autoriteit 4%
Iedereen heeft al aangegeven (aanbevolen) het gebruik van paramikoen ik deel alleen een python-code (API zou je kunnen zeggen) waarmee je meerdere opdrachten in één keer kunt uitvoeren.
om commando’s uit te voeren op verschillende nodes, gebruik: Commands().run_cmd(host_ip, list_of_commands)
Je zult één TODO zien, die ik heb bewaard om de uitvoering te stoppen als een van de opdrachten niet wordt uitgevoerd, ik weet niet hoe ik het moet doen. deel alsjeblieft je kennis
#!/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:])
Bedankt!
Antwoord 6, autoriteit 3%
paramikowerkte eindelijk voor mij na het toevoegen van een extra regel, wat erg belangrijk is (regel 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)
Zorg ervoor dat het paramiko-pakket is geïnstalleerd.
Originele bron van de oplossing: Bron
Antwoord 7, autoriteit 2%
Ik heb paramikoeen heleboel (leuk) en pxssh(ook leuk). Ik zou het ook aanraden. Ze werken een beetje anders, maar hebben een relatief grote overlap in gebruik.
Antwoord 8, autoriteit 2%
Het geaccepteerde antwoord werkte niet voor mij, dit is wat ik in plaats daarvan heb gebruikt:
import paramiko
import os
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# ssh.load_system_host_keys()
ssh.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
ssh.connect("d.d.d.d", username="user", password="pass", port=22222)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("ls -alrt")
exit_code = ssh_stdout.channel.recv_exit_status() # handles async exit error
for line in ssh_stdout:
print(line.strip())
total 44
-rw-r--r--. 1 root root 129 Dec 28 2013 .tcshrc
-rw-r--r--. 1 root root 100 Dec 28 2013 .cshrc
-rw-r--r--. 1 root root 176 Dec 28 2013 .bashrc
...
Als alternatief kunt u sshpass:
gebruiken
import subprocess
cmd = """ sshpass -p "myPas$" ssh [email protected] -p 22222 'my command; exit' """
print( subprocess.getoutput(cmd) )
Referenties:
Opmerkingen:
- Zorg ervoor dat je minimaal één keer handmatig verbinding maakt met het externe systeem via ssh (
ssh root@ip
) en accepteer de openbare sleutel, dit is vele malen de reden om geen verbinding te kunnen maken met behulp vanparamiko
of andere geautomatiseerdessh
-scripts.
Antwoord 9
Werkt perfect…
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()
10
U kunt een van deze opdrachten gebruiken, dit zal u ook helpen om een wachtwoord te geven.
cmd = subprocess.run(["sshpass -p 'password' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null [email protected] ps | grep minicom"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print(cmd.stdout)
OR
cmd = subprocess.getoutput("sshpass -p 'password' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null [email protected] ps | grep minicom")
print(cmd)
11
Gebruiker vragen om de opdracht in te voeren volgens het apparaat dat ze inloggen.
De onderstaande code is gevalideerd door 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)
Antwoord 12
#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)
Antwoord 13
Hieronder voorbeeld, indien u gebruikersinvoer wilt voor hostnaam, gebruikersnaam, wachtwoord en poortnummer.
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()