पायथन के साथ ssh पर कमांड करें


136

मैं पायथन में कुछ कमांड लाइन कमांड को स्वचालित करने के लिए एक स्क्रिप्ट लिख रहा हूं। फिलहाल मैं इस प्रकार कॉल कर रहा हूं:

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

हालाँकि मुझे रिमोट मशीन पर कुछ कमांड चलाने की आवश्यकता है। मैन्युअल रूप से, मैं ssh का उपयोग करने में लॉग इन करूंगा और फिर कमांड चलाऊंगा। मैं इसे पायथन में कैसे स्वचालित करूंगा? मुझे रिमोट मशीन के लिए एक (ज्ञात) पासवर्ड के साथ लॉग इन करने की आवश्यकता है, इसलिए मैं सिर्फ उपयोग नहीं कर सकता cmd = ssh user@remotehost, मैं सोच रहा हूं कि क्या कोई मॉड्यूल है जिसका मुझे उपयोग करना चाहिए?

जवाबों:


201

मैं आपको पैरामिको का उल्लेख करूंगा

इस प्रश्न को देखें

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

3
यहाँ धारणा यह है कि पैरामीको उतना ही सुरक्षित (खुला) ssh है। क्या यह?
user239558

1
क्या होगा अगर ssh- कुंजी का आदान-प्रदान किया जाता है?
अर्दित

19
यदि आप SSH कुंजियों का उपयोग कर रहे हैं, तो पहले EITHER: k = paramiko.RSAKey.from_private_key_file(keyfilename)OR k = paramiko.DSSKey.from_private_key_file(keyfilename)THEN ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())और अंत में कीफाइल तैयार करें ssh..connect(hostname=host, username=user, pkey=k)
स्कॉट प्रिव

7
Paramiko (लेकिन विशेषज्ञ नहीं) के एक लंबे समय के उपयोगकर्ता के रूप में, मैं Paramiko का उपयोग करने का सुझाव दे सकता हूं लेकिन आपको अपने उपयोग के मामलों पर विचार करना चाहिए और आप कितना सीखने के लिए तैयार हैं। Paramiko बहुत निम्न-स्तर है, और आप आसानी से एक जाल में गिर सकते हैं जहाँ आप "कमांड रनिंग हेल्पर फंक्शन" बनाते हैं, जो आपके द्वारा उपयोग किए जा रहे कोड को पूरी तरह से समझे बिना। इसका मतलब def run_cmd(host, cmd):है कि आप ऐसा कह सकते हैं कि जो आप पहले चाहते हैं वह करें, लेकिन आपकी जरूरतें विकसित होती हैं। आप नए उपयोग के मामले के लिए सहायक को बदलना समाप्त करते हैं, जो पुराने मौजूदा उपयोग के व्यवहार को बदलता है। तदनुसार योजना बनाएं।
स्कॉट प्रिव

3
अज्ञात होस्ट त्रुटि के लिए, ऐसा करें: ssh.set_missing_host_key_policy (paramiko.AutoAddPolicy ()) से पहले
निमो

49

या आप बस कमांड का उपयोग कर सकते हैं ।getstatusoutput :

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

मैंने इसे बड़े पैमाने पर इस्तेमाल किया और यह बढ़िया काम करता है।

पायथन 2.6+ में, का उपयोग करें subprocess.check_output


4
एक अच्छी सरल अंतर्निहित पद्धति के लिए +1। अपने वर्तमान सेटअप में मैं अजगर पुस्तकालयों को जोड़ना नहीं चाहता हूं, इसलिए आपका सुझाव मूल्यवान है, बहुत सीधा भी।
फिलिप किर्न्स

3
बस यह सुनिश्चित करें कि आपका रिमोट होस्ट
पासवर्डलेस

subprocess.check_output - बढ़िया समाधान!
टिम एस।

2
@powerrox वे "अन्य चीजें क्या हैं?"
ईगलन

2
@TimS। आपको अपने सेटअप के लिए जो भी उपयुक्त हो, प्रमाणीकरण के लिए हैंडलिंग को शामिल करना पड़ सकता है। मैं प्रॉम्प्ट पर पासवर्ड दर्ज करने की उम्मीद करता था। इसके बाद अन्य समाधानों के साथ यह धागा है: unix.stackexchange.com/questions/147329/…
powerrox

29

क्या आपने फैब्रिक पर एक नजर डाली है ? यह आपको अजगर का उपयोग करके SSH पर सभी प्रकार के दूरस्थ सामान करने की अनुमति देता है।


18

मैंने पाया कि परमिको थोड़ा निम्न स्तर का है, और फैब्रिक विशेष रूप से अच्छी तरह से एक पुस्तकालय के रूप में उपयोग किए जाने के लिए अनुकूल नहीं है, इसलिए मैंने अपने स्वयं के पुस्तकालय को स्पर कहा जाता है, जो थोड़ा सा अच्छे इंटरफ़ेस को लागू करने के लिए परमिको का उपयोग करता है:

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"])

2
मैंने कोशिश करने का फैसला किया spur। आप अतिरिक्त शेल कमांड उत्पन्न करते हैं और आप के साथ समाप्त होते हैं: जो 'mkdir'> / dev / null 2> & 1; गूंज $ ;; 'mkdir' '-p' '/ data / rpmupdate / 20130207142923' निष्पादित करें। मैं एक मैदान तक भी पहुंचना चाहूंगा exec_command। पृष्ठभूमि कार्यों को चलाने की क्षमता भी गायब है nohup ./bin/rpmbuildpackages < /dev/null >& /dev/null &:। उदाहरण के लिए, मैं टेम्पलेट का उपयोग करके एक zsh स्क्रिप्ट (rpmbuildpackages) उत्पन्न करता हूं और फिर मैं इसे मशीन पर चलाना छोड़ देता हूं। हो सकता है कि इस तरह के बैकग्राउंड जॉब पर नजर रखने की क्षमता भी अच्छी हो (कुछ ~ / .spur में पीआईडी ​​की बचत)।
davidlt

1
spurजाहिरा तौर पर केवल यूनिक्स सिस्टम पर काम करता है क्योंकि यह एक निर्भरता है termios। क्या कोई विंडोज के लिए एक अच्छी लाइब्रेरी जानता है?
गेब्रियल

पूरी तरह से सच नहीं है: यदि आप एक पूर्व-स्थापित इंस्टॉलर का उपयोग करते हैं , तो आप पैरामिको और स्पर को स्थापित करने में सक्षम होंगे। मैंने इसे खुद किया था ...
रवेमिर

@ गैब्रिएल: हालिया रिलीज में से एक को विंडोज पर समर्थन में सुधार होना चाहिए। यदि यह अभी भी काम नहीं कर रहा है, तो कृपया एक मुद्दा खोलने के लिए स्वतंत्र महसूस करें।
माइकल विलियमसन

@davidlt: निर्माण करते समय SshShell, अब शेल प्रकार सेट करने का विकल्प है। यदि एक न्यूनतम शेल को पास करके उपयोग किया जाता है shell_type=spur.ssh.ShellTypes.minimal, तो केवल कच्चा कमांड भेजा जाता है। बैकग्राउंड टास्क को लागू करना सीधे तौर पर स्पर के लिए थोड़ा सा दायरे से बाहर लगता है, लेकिन आपको उस कमांड को चलाने में सक्षम होना चाहिए जिसे आपने शेल के नाम से वर्णित किया है shell.run(["sh", "-c", "nohup ./bin/rpmbuildpackages < /dev/null >& /dev/null &"])।
माइकल विलियमसन

18

इसे सरल रखें। किसी पुस्तकालय की आवश्यकता नहीं है।

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()

1
सबप्रोसेस ऑटोमेशन में आपकी स्विस आर्मी चाकू है। फिर आप शेल स्क्रिप्ट, sed, awk, grep जैसी अंतहीन संभावनाओं के साथ अजगर को जोड़ सकते हैं। हाँ, आप सभी अजगर में कर सकते हैं, लेकिन यह सिर्फ अजगर में कहीं न कहीं एक grep चलाने के लिए बहुत अच्छा होगा - अच्छी तरह से कर सकते हैं।
रॉन मैकक

12
यदि आपका ssh कमांड पासवर्ड मांगता है तो आप पायथन फाइल में उसे कैसे प्रदान करेंगे?
बीइंगसुमन

1
@BeingSuman आप उसके लिए SSH कुंजी प्रमाणीकरण का उपयोग कर सकते हैं। हालांकि मुझे लगता है कि आपने पहले ही पता लगा लिया है।
शाम

9

सभी ने पहले ही पैरामीको का उपयोग करके (अनुशंसित) कहा है और मैं सिर्फ एक अजगर कोड (एपीआई एक कह सकता हूं) साझा कर रहा हूं जो आपको एक बार में कई कमांड निष्पादित करने की अनुमति देगा।

विभिन्न नोड उपयोग पर कमांड निष्पादित करने के लिए: 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

मैं paramiko एक गुच्छा (अच्छा) और pxssh (भी अच्छा) का उपयोग किया है। मैं या तो सिफारिश करेंगे। वे थोड़े अलग तरीके से काम करते हैं लेकिन उपयोग में अपेक्षाकृत बड़े ओवरलैप होते हैं।


4
Pxssh की कड़ी समय में एक अच्छी यात्रा है।
ओबेन सोन

3

पैरामीको ने अतिरिक्त पंक्ति जोड़ने के बाद आखिरकार मेरे लिए काम किया, जो वास्तव में महत्वपूर्ण है (पंक्ति 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)

सुनिश्चित करें कि पैरामिको पैकेज स्थापित है। समाधान का मूल स्रोत: स्रोत


1
#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

अच्छी तरह से काम...

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()

1

स्वीकृत उत्तर मेरे काम नहीं आया, यहाँ मैंने इसके बजाय क्या प्रयोग किया है:

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
...

वैकल्पिक रूप से, आप sshpass का उपयोग कर सकते हैं :

import subprocess
cmd = """ sshpass -p "myPas$" ssh user@d.d.d.d -p 22222 'my command; exit' """
print( subprocess.getoutput(cmd) )

संदर्भ:
1. https://github.com/onyxfish/relay/issues/11
2. https://stackoverflow.com/a/61016663/797495


0

एक नज़र spurplusडालिए, एक रैपर जो हमने विकसित किया है spur, जो टाइप एनोटेशन और कुछ छोटी-छोटी नौटंकी (SFTP, md5 आदि को फिर से जोड़ने ) प्रदान करता है: https://pypi.org/project/spurplus/


1
एक रैपर के चारों ओर एक आवरण के आसपास एक आवरण .. अच्छा :)
एलेक्स आर

ठीक है, यदि आप अपनी तैनाती लिपियों को तुच्छ रखना चाहते हैं, तो मुझे संदेह है कि अंतर्निहित उपकरण सरल / पर्याप्त हैं। अब तक, हमने टकटकी के सार का निरीक्षण नहीं किया।
marko.ristin

0

उपयोगकर्ता को लॉग इन करने वाले डिवाइस के अनुसार कमांड दर्ज करने के लिए
कहना। नीचे कोड 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

यदि आप होस्टनाम, उपयोगकर्ता नाम, पासवर्ड और पोर्ट नं।

  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()

5
बेहतर फॉर्मेटिंग के साथ दो दिन पहले से अपने उत्तर को रीपोस्ट करने के बजाय, पुराने उत्तर को क्यों न संपादित करें और इसकी फॉर्मेटिंग में सुधार करें?
सांचेचरम्ब
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.