Я пытаюсь протестировать, если файл существует по 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()
Спасибо за любую справку.
Если сервер принимает сеансы sftp, я бы не стал беспокоиться о pexpect , но вместо этого используйте модуль SSH2 paramiko для 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_c ommand возвращает тройку (stdin, stdout, stderr). Здесь мы просто проверяем наличие какого-либо вывода. Вместо этого вы можете изменить команду или проверить stderr на наличие сообщений об ошибках.
Когда вы как пользователь введите что-то в 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'])
Почему бы не воспользоваться тем фактом, что код возврата команды передается обратно по 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
Таким образом, вы можете просто проверить код возврата без необходимости захват вывода.
У меня нет опыта pexpect, но, глядя на их веб-страницу, похоже, что вы можете вызвать метод expect с несколькими значениями, и он возвращает индекс тот, которому он соответствует (это основано исключительно на том, что я просто смотрю на этот пример).
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'))]
Я разработал решение, которое меня устраивает. Код ниже:
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' в строковом формате. Затем я разбиваю строку, чтобы получить строку «Файл существует» в список и сравнивать ее с ответом, который я ищу. Если файл не существует, проверка не удастся.
Спасибо за помощь.