SCP файл tar с использованием pexpect - PullRequest
1 голос
/ 16 июня 2010

Я использую ssh для входа в камеру, scp тарбол к ней, извлечение файлов из тарбала и запуск скрипта.У меня проблемы с Pexpect.Pexpect истекает, когда архив копируется.Кажется, не стоит ждать, пока это не будет сделано.И затем он начинает делать то же самое с командой untar, код, который я имею ниже:

    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

Может кто-нибудь помочь найти решение для этого?

Спасибо

Ответы [ 2 ]

2 голосов
/ 16 июня 2010

Я не уверен, что это правильно, но я бы попробовал установить время ожидания на None:

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

Согласно исходному коду, pexpect, похоже, не проверяет время ожидания, когда оноустановите на None.

В любом случае, причина, по которой я отвечаю на это, хотя я не уверен, решит ли это вашу проблему, заключается в том, что я хотел бы рекомендовать вместо этого использовать paramiko .В прошлом у меня был хороший опыт использования его для связи через SSH.

1 голос
/ 25 марта 2014

Есть ли причина, по которой вы используете pexpect или даже paramiko?

если вы установили открытый / закрытый ключ, то вы можете просто использовать в качестве одного примера:

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

Затем, согласно предложению выше, используйте paramiko для отправки команд.

вы также можете использовать ключевой файл для этого:

Следующий метод класса даст вам постоянный сеанс (хотя он не проверен):

#!/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()
...