2011-06-01 13 views
32
def exec_command(self, command, bufsize=-1): 
    #print "Executing Command: "+command 
    chan = self._transport.open_session() 
    chan.exec_command(command) 
    stdin = chan.makefile('wb', bufsize) 
    stdout = chan.makefile('rb', bufsize) 
    stderr = chan.makefile_stderr('rb', bufsize) 
    return stdin, stdout, stderr 

paramiko में कमांड निष्पादित करते समय, यह exec_command चलाते समय हमेशा सत्र को रीसेट करता है। मैं सूडो या सु निष्पादित करने में सक्षम होना चाहता हूं और जब भी मैं एक और exec_command चलाता हूं तब भी उन विशेषाधिकारों को प्राप्त करना चाहता हूं। एक और उदाहरण exec_command ("cd /") को करने का प्रयास करेगा और फिर exec_command को फिर से चलाएगा और यह रूट निर्देशिका में होगा। मुझे पता है कि आप exec_command ("cd /; ls -l") जैसे कुछ कर सकते हैं, लेकिन मुझे इसे अलग-अलग फ़ंक्शन कॉल में करने की आवश्यकता है।पैरामीको में एक सत्र में आप एकाधिक कमांड कैसे निष्पादित करते हैं? (पायथन)

उत्तर

34

गैर इंटरएक्टिव उपयोग के मामलों

यह एक गैर-सहभागी उदाहरण है ... भेजता cd tmp, ls और फिर exit

import sys 
sys.stderr = open('/dev/null')  # Silence silly warnings from paramiko 
import paramiko as pm 
sys.stderr = sys.__stderr__ 
import os 

class AllowAllKeys(pm.MissingHostKeyPolicy): 
    def missing_host_key(self, client, hostname, key): 
     return 

HOST = '127.0.0.1' 
USER = '' 
PASSWORD = '' 

client = pm.SSHClient() 
client.load_system_host_keys() 
client.load_host_keys(os.path.expanduser('~/.ssh/known_hosts')) 
client.set_missing_host_key_policy(AllowAllKeys()) 
client.connect(HOST, username=USER, password=PASSWORD) 

channel = client.invoke_shell() 
stdin = channel.makefile('wb') 
stdout = channel.makefile('rb') 

stdin.write(''' 
cd tmp 
ls 
exit 
''') 
print stdout.read() 

stdout.close() 
stdin.close() 
client.close() 

इंटरएक्टिव उपयोग के मामलों
आप एक इंटरैक्टिव उपयोग के मामले है, इस सवाल का जवाब में मदद नहीं करेगा ... मैं व्यक्तिगत रूप से इंटरैक्टिव सत्र के लिए pexpect या exscript का प्रयोग करेंगे।

+2

पर कोड जोड़ना लेकिन यह समाधान सभी आदेश समाप्त होने से पहले पहले कमांड के आउटपुट को पढ़ने की अनुमति नहीं देता है। क्या मैं सही हू? –

+1

यह काम नहीं करता है क्योंकि stdout.read() पूरी फ़ाइल को पढ़ता है। मतलब, यह प्रोग्राम को पढ़ता है जो टर्मिनल पर "टाइप किया गया" था। यह इरादा व्यवहार नहीं है। आप पूरे कार्यक्रम के बजाय केवल 'एलएस' के आउटपुट और' एलएस' के आउटपुट को कैसे पढ़ते हैं? –

+0

मैं उपरोक्त दो टिप्पणियों के साथ हूं ... सभी आदेशों से पहले एक कमांड के आउटपुट को पढ़ने के लिए कोई तरीका समाप्त हो गया है? – dmranck

19

कड़ाई से बोलते हुए, आप नहीं कर सकते। एसएसएच स्पेक के अनुसार:

एक सत्र एक कार्यक्रम का दूरस्थ निष्पादन है। कार्यक्रम खोल, एक अनुप्रयोग, एक सिस्टम कमांड, या कुछ अंतर्निहित सबसिस्टम हो सकता है।

इसका मतलब है कि, आदेश कम हो जाने के बाद, सत्र समाप्त हो गया है। आप एक सत्र में एकाधिक कमांड निष्पादित नहीं कर सकते हैं। आप क्या कर सकते हैं, हालांकि, एक दूरस्थ खोल (== एक कमांड) शुरू कर रहा है, और उस शैल के साथ stdin आदि के माध्यम से बातचीत कर रहा है ... (एक पाइथन स्क्रिप्ट बनाम इंटरैक्टिव दुभाषिया चलाने के बारे में सोचें)

+1

एसएसएच आरएफसी इस बारे में नहीं कहता है कि आदेश निष्पादित करने के तुरंत बाद सत्र समाप्त किया जाना चाहिए या नहीं। यदि आपने अधिकांश एसएसएच क्लाइंट को देखा है, तो सत्र स्थापित होने के बाद वे एक्सेल/शैल खोलते रहते हैं। उपयोगकर्ता को किसी भी संख्या कमांड टाइप करने की अनुमति है। जब उपयोगकर्ता "बाहर निकलें" टाइप करता है तो केवल सत्र समाप्त हो जाता है। –

3

बनाने का प्रयास करें \n वर्ण से अलग एक कमांड स्ट्रिंग। यह मेरे लिए काम किया। के लिए। जैसे ssh.exec_command("command_1 \n command_2 \n command_3")

2
cmd = 'ls /home/dir' 
self.ssh_stdin, self.ssh_stdout, self.ssh_stderr = self.ssh.exec_command(cmd) 
print self.ssh_stdout.read() 
cmd2 = 'cat /home/dir/test.log' 
self.ssh_stdin2, self.ssh_stdout2, self.ssh_stderr2 = self.ssh.exec_command(cmd2) 
print self.ssh_stdout2.read() 
0

आप क्लाइंट पर खोल खोलकर और आदेश भेजकर ऐसा कर सकते हैं। कृपया here
पृष्ठ पर पायथन 3.5 के लिए कोड है। मैंने पायथन 2.7 के लिए काम करने के लिए थोड़ा सा कोड संशोधित किया है। संदर्भ

import threading, paramiko 

strdata='' 
fulldata='' 

class ssh: 
    shell = None 
    client = None 
    transport = None 

    def __init__(self, address, username, password): 
     print("Connecting to server on ip", str(address) + ".") 
     self.client = paramiko.client.SSHClient() 
     self.client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy()) 
     self.client.connect(address, username=username, password=password, look_for_keys=False) 
     self.transport = paramiko.Transport((address, 22)) 
     self.transport.connect(username=username, password=password) 

     thread = threading.Thread(target=self.process) 
     thread.daemon = True 
     thread.start() 

    def closeConnection(self): 
     if(self.client != None): 
      self.client.close() 
      self.transport.close() 

    def openShell(self): 
     self.shell = self.client.invoke_shell() 

    def sendShell(self, command): 
     if(self.shell): 
      self.shell.send(command + "\n") 
     else: 
      print("Shell not opened.") 

    def process(self): 
     global strdata, fulldata 
     while True: 
      # Print data when available 
      if self.shell is not None and self.shell.recv_ready(): 
       alldata = self.shell.recv(1024) 
       while self.shell.recv_ready(): 
        alldata += self.shell.recv(1024) 
       strdata = strdata + str(alldata) 
       fulldata = fulldata + str(alldata) 
       strdata = self.print_lines(strdata) # print all received data except last line 

    def print_lines(self, data): 
     last_line = data 
     if '\n' in data: 
      lines = data.splitlines() 
      for i in range(0, len(lines)-1): 
       print(lines[i]) 
      last_line = lines[len(lines) - 1] 
      if data.endswith('\n'): 
       print(last_line) 
       last_line = '' 
     return last_line 


sshUsername = "SSH USERNAME" 
sshPassword = "SSH PASSWORD" 
sshServer = "SSH SERVER ADDRESS" 


connection = ssh(sshServer, sshUsername, sshPassword) 
connection.openShell() 
connection.send_shell('cmd1') 
connection.send_shell('cmd2') 
connection.send_shell('cmd3') 
time.sleep(10) 
print(strdata) # print the last line of received data 
print('==========================') 
print(fulldata) # This contains the complete data received. 
print('==========================') 
connection.close_connection() 
संबंधित मुद्दे