2010-06-16 27 views
1

J'utilise ssh pour se connecter à un appareil photo, scp une tarball dessus et extraire les fichiers à partir du tarbal, puis exécutez le script. J'ai des problèmes avec Pexpect, cependant. Pexpect expire lorsque l'archive est copiée. Il semble ne pas attendre jusqu'à ce que ce soit fait. Et alors il est de commencer à faire la même chose avec la commande décompressez, le code que j'ai est ci-dessous:SCP un fichier tar en utilisant pexpect

ssh_newkey = 'Are you sure you want to continue connecting'   
    copy = pexpect.spawn('ssh [email protected]') 
    i=copy.expect([ssh_newkey,'password:',pexpect.EOF]) 
    if i==0: 
     copy.sendline('yes') 
     i=copy.expect([ssh_newkey,'password:',pexpect.EOF]) 
    if i==1:   
     copy.sendline("service") 
     print 'Password Accepted' 
     copy.expect('[email protected]:') 
     copy.sendline('su - root') 
     i=copy.expect('Password:') 
     copy.sendline('root') 
     i=copy.expect('#') 
     copy.sendline('cd /tmp') 
     i=copy.expect("#") 
     copy.sendline('scp [email protected]:/home/user/tarfile.tar.gz .') 
     i=copy.expect([ssh_newkey,'password:',pexpect.EOF]) 
     if i==0: 
      copy.sendline('yes') 
      i=copy.expect([ssh_newkey,'password:',pexpect.EOF]) 
     else: 
      pass 
     copy.sendline('userpwd') 
     i=copy.expect('#') 
     copy.sendline('tar -zxvf tarfile.tar.gz bin/installer.sh') 
     i=copy.expect("#") 
     copy.sendline("setsid /tmp/bin/installer.sh /tmp/tarfile.tar.gz > /dev/null 2>&1 &")    
    elif i==2: 
     print "I either got key or connection timeout" 
    else: 
     pass 

Quelqu'un peut-il aider à trouver une solution pour cela?

Merci

+0

Pouvez-vous fermer la citation @ la ligne 2DN , donc ça va imprimer plus gentil? –

Répondre

2

Je ne sais pas si cela est correct, mais je vais essayer de définir le délai d'None:

copy = pexpect.spawn('ssh [email protected]', timeout=None) 

Selon le code source, pexpect semble ne pas vérifier le délai d'attente lorsqu'il est défini sur None.

Quoi qu'il en soit, la raison pour laquelle je réponds à cette question, même si je ne suis pas sûr si elle résout votre problème, c'est que je voulais recommander d'utiliser paramiko à la place. J'avais une bonne expérience de l'utilisation pour la communication sur SSH dans le passé.

+0

áš - Je me sens un peu bête maintenant, je n'y ai jamais pensé. Le délai d'attente est défini sur 30 secondes et le tarbal prend plus de temps à copier. Ce travail est maintenant. Merci +1 – chrissygormley

1

Y a-t-il une raison pour laquelle vous utilisez pexpect ou même paramiko?

si vous configurez une public/private clé, vous pouvez simplement utiliser comme un seul exemple:

command = "scp [email protected]:/home/user/tarfile.tar.gz" 
split_command = shlex.split(command) 
subprocess.call(split_command) 

Ensuite, selon la suggestion ci-dessus utilisent paramiko pour envoyer des commandes.

vous pouvez utiliser KeyFile pour cela aussi:

La méthode de classe suivante vous donnera une session persistante (bien qu'il soit non testé):

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

from __future__ import print_function 
import os 
from paramiko import SSHClient, AutoAddPolicy, AuthenticationException, RSAKey 
from subprocess import call 

class CommsSuite(object): 

    def __init__(self): 
     self.ssh_client = SSHClient() 

     #-------------------------------------- 

     def _session_send(command): 
      """ 
      Use to send commands over ssh in a 'interactive_session' 
      Verifies session is present 
      If the interactive_session is not present then print the failed command. 

      This may be updated to raise an error, 
      which would probably make more sense. 

      @param command: the command to send across as a string 

      ::TODO:: consider raise exception here as failed 
         session will most likely be fatal. 

      """ 

      if self.session.send_ready(): 
       self.session.send("%s\n" % command) 
      else: 
       print("Session cannot send %s" % command) 

     #-------------------------------------- 

     def _get_persistent_session(_timeout = 5): 
      """ 
      connect to the host and establish an interactive session. 

      @param _timeout: sets the timout to prevent blocking. 

      """ 
      privatekeyfile = os.path.expanduser('~/.ssh/id_rsa')#this must point to your keyfile 

      private_key = RSAKey.from_private_key_file(privatekeyfile) 
      self.ssh_client.set_missing_host_key_policy(AutoAddPolicy()) 

      self.ssh_client.connect(hostname, 
            username = <username>, 
            pkey = private_key, 
            timeout = _timeout) 

      self.transport = self.ssh_client.get_transport() 
      self.session = self.transport.open_session() 
      self.session.exec_command("bash -s") 

     _get_persistent_session() 


     # build a comma seperated list of commands here as a string "[a,b,c]" 
     commands = ["tar -zxvf tarfile.tar.gz bin/installer.sh", "setsid /tmp/bin/installer.sh /tmp/tarfile.tar.gz > /dev/null 2>&1"] 
     # then run the list of commands 
     if len(commands) > 0: 
      for command in commands: 
       _session_send(command) 

     self.session.close()#close the session when done 


CommsSuite()