Pergunta

estou usando ssh Para fazer login em uma câmera, scp Um tarball até ele e extraia arquivos do Tarbal e depois execute o script. Estou tendo problemas com o Pexpect, no entanto. O Pexpect Out Out quando o tarball está sendo copiado. Parece não esperar até que seja feito. E então ele começa a fazer a mesma coisa com o comando untar, o código que tenho está abaixo:

    ssh_newkey = 'Are you sure you want to continue connecting'          
    copy = pexpect.spawn('ssh service@10.10.10.10')
    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('service@user:')
        copy.sendline('su - root')
        i=copy.expect('Password:')
        copy.sendline('root')
        i=copy.expect('#')
        copy.sendline('cd /tmp')
        i=copy.expect("#")
        copy.sendline('scp user@20.20.20.20:/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

Alguém pode ajudar a encontrar uma solução para isso?

Obrigado

Foi útil?

Solução

Não tenho certeza se isso está correto, mas tentaria definir o tempo limite para None:

copy = pexpect.spawn('ssh service@10.10.10.10', timeout=None)

De acordo com o código -fonte, Pexpect parece não verificar o tempo limite quando está definido como None.

De qualquer forma, a razão pela qual estou respondendo isso, mesmo que não tenha certeza se resolve o seu problema é que eu queria recomendar o uso Paramiko em vez de. Eu tive uma boa experiência de usá -lo para comunicação sobre SSH no passado.

Outras dicas

Existe uma razão pela qual você está usando pexpect ou mesmo paramiko?

Se você configurar um público Privado Tecla então você pode apenas usar como um único exemplo:

command = "scp user@20.20.20.20:/home/user/tarfile.tar.gz"
split_command = shlex.split(command)
subprocess.call(split_command)

Então, de acordo com a sugestão acima, use o paramiko para enviar comandos.

Você pode usar o arquivo de chave para isso também:

O método de classe a seguir fornecerá uma sessão persistente (embora não seja testada):

#!/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()
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top