Убедитесь, что файл существует через SSH - PullRequest
5 голосов
/ 03 февраля 2010

Я пытаюсь проверить, существует ли файл через SSH, используя pexpect. У меня большая часть кода работает, но мне нужно поймать значение, чтобы я мог утверждать, существует ли файл. Код, который я сделал ниже:

def VersionID():

        ssh_newkey = 'Are you sure you want to continue connecting'
        # my ssh command line
        p=pexpect.spawn('ssh service@10.10.0.0')

        i=p.expect([ssh_newkey,'password:',pexpect.EOF])
        if i==0:
            p.sendline('yes')
            i=p.expect([ssh_newkey,'password:',pexpect.EOF])
        if i==1:
            p.sendline("word")
            i=p.expect('service@main-:')
            p.sendline("cd /opt/ad/bin")
            i=p.expect('service@main-:')
            p.sendline('[ -f email_tidyup.sh ] && echo "File exists" || echo "File does not exists"')
            i=p.expect('File Exists')
            i=p.expect('service@main-:')
            assert True
        elif i==2:
            print "I either got key or connection timeout"
            assert False

        results = p.before # print out the result

VersionID()

Спасибо за любую помощь.

Ответы [ 6 ]

9 голосов
/ 03 февраля 2010

Почему бы не воспользоваться тем, что код возврата команды передается обратно по SSH?

$ ssh victory 'test -f .bash_history'
$ echo $?
0
$ ssh victory 'test -f .csh_history'
$ echo $?
1
$ ssh hostdoesntexist 'test -f .csh_history'
ssh: Could not resolve hostname hostdoesntexist: Name or service not known
$ echo $?
255

Таким образом, вы можете просто проверить код возврата без необходимости записывать вывод.

4 голосов
/ 03 февраля 2010

Если сервер принимает сеансы sftp, я не стал бы беспокоиться о pexpect, но вместо этого использовал бы модуль paramiko SSH2 для Python:

import paramiko
transport=paramiko.Transport("10.10.0.0")
transport.connect(username="service",password="word")
sftp=paramiko.SFTPClient.from_transport(transport)
filestat=sftp.stat("/opt/ad/bin/email_tidyup.sh")

Код открывает SFTPClient соединение с сервером, на котором вы можете использовать stat () для проверки наличия файлов и каталогов.

sftp.stat вызовет ошибку IOError («Нет такого файла»), когда файлне существует.

Если сервер не поддерживает sftp, это будет работать:

import paramiko
client=paramiko.SSHClient()
client.load_system_host_keys()
client.connect("10.10.0.0",username="service",password="word")
_,stdout,_=client.exec_command("[ -f /opt/ad/bin/email_tidyup.sh ] && echo OK")
assert stdout.read()

SSHClient.exec_command возвращает тройку (stdin, stdout, stderr).Здесь мы просто проверяем наличие какого-либо вывода.Вместо этого вы можете изменить команду или проверить stderr на наличие сообщений об ошибках.

2 голосов
/ 12 ноября 2013

У меня были некоторые проблемы с этим, когда каждый раз, когда я запускал свою программу, она меняла вывод. например Если бы я искал /bin/bash, иногда возвращалось бы, что оно было найдено, а в других случаях возвращалось, что оно пропало.

Я получил следующий код для согласованной работы с файлами и папками, предшествовавший тому, что я ожидал, с \r\n

# returns 0 if the file is missing and 1 if the file exists
# if ( hostFileExists( host, '/bin/sh/' ) == 1 ): echo "File exists!"
def hostFileExists( host, theFile ):
    host.sendline( '[ ! -e %r ] && echo NO || echo YES' % theFile )
    return host.expect( ["\r\nNO", "\r\nYES"] )

или

# provide the host, the command, and the expectation
# command = '[ ! -e "/bin/sh" ] && echo NO || echo YES'
# expecting = ['NO', 'YES']
# i = hostExpect( host, command, expecting )
# if ( i == 1 ): echo "File exists!"
def hostExpect( host, command, expect ):
    newExpect = []
    for e in expect:
        newExpect.append( "\r\n%s" % e )
    host.sendline( command )
    return host.expect( newExpect )

Надеюсь, это поможет вам.

Редактировать: Также заметил, что когда ssh'ing в Windows (cygwin) и пытается увидеть, существует ли файл, файл должен быть в кавычках. В Linux это необязательно. Таким образом, %s в host.sendline был изменен на %r.

0 голосов
/ 03 февраля 2010

Я разработал решение, которое сделает меня. Код ниже:

def VersionID(): 

    ssh_newkey = 'Are you sure you want to continue connecting' 
    # my ssh command line 
    p=pexpect.spawn('ssh service@10.10.0.0') 

    i=p.expect([ssh_newkey,'password:',pexpect.EOF]) 
    if i==0: 
        p.sendline('yes') 
        i=p.expect([ssh_newkey,'password:',pexpect.EOF]) 
    if i==1: 
        p.sendline("word") 
        i=p.expect('service@main-:') 
        p.sendline("cd /opt/ad/bin") 
        i=p.expect('service@main-:') 
        p.sendline('[ -f email_tidyup.sh ] && echo "File exists" || echo "File does not exists"') 
        i=p.expect('service@main-:') 
        assert True 
    elif i==2: 
        print "I either got key or connection timeout" 
        assert False 


        results = p.before # print out the result
        print results
        value = results.split('"')[8]
        split_value = value.split('\r\n')[1:-1]
        self.assertEquals(split_value, ['File exists'])

Это извлекает значение из 'p' в строковом формате. Затем я разбил строку, чтобы получить строку «Файл существует», и сравнил ее с ответом, который я ищу. Если файл не существует, тест не пройден.

Спасибо за помощь.

0 голосов
/ 03 февраля 2010

Когда вы как пользователь вводите что-то в ssh, оболочка будет отображать символы обратно. Это происходит и сейчас.

Итак, делаем:

p.sendline('test -f email_tidyup.sh && echo "File exists" || echo "File does not exist"')

Результатом будет:

service@main-: test -f email_tidy.sh && echo "File exists" || echo "File does not exists"
File does not exist

Делать:

i = p.expect(['File exists', 'File does not exist'])

В этом случае всегда будет i == 0, потому что «Файл существует» присутствует в первой строке, полученной обратно.

Альтернатива, в которой исходная строка отправки не имеет ожидаемого предложения:

p.sendline('test -f email_tidyup.sh; echo result: $?')
i = p.expect('result: 0', 'result: 1')

Или больше похоже на оригинал:

p.sendline('[ -f email_tidyup.sh ] && echo "File exists" || echo "File does not exist"')
i = p.expect(['\nFile exists', '\nFile does not exist'])
0 голосов
/ 03 февраля 2010

У меня нет никакого опыта pexpect, но, глядя на их веб-страницу, похоже, что вы можете вызвать методpect с несколькими значениями, и он возвращает индекс того, который ему соответствует (это основано исключительно на том, что я просто смотрю наэтот пример).

child.expect('password:')
child.sendline (my_secret_password)
# We expect any of these three patterns...
i = child.expect (['Permission denied', 'Terminal type', '[#\$] '])
if i==0:
    print 'Permission denied on host. Can't login'
    child.kill(0)
elif i==2:
    print 'Login OK... need to send terminal type.'
    child.sendline('vt100')
    child.expect ('[#\$] ')
elif i==3:
    print 'Login OK.'
    print 'Shell command prompt', child.after

На самом деле, вы уже используете эту функцию вверху.

Итак, вы хотите узнать, существует файл или нет? ...

Попробуйте это ...

        p.sendline('[ -f email_tidyup.sh ] && echo "File exists" || echo "File does not exists"')
        file_exists = {0: True, 1: False}[p.expect(('File Exists', 'File does not exists'))]
...