Использование expect для получения выходных данных из ssh

#python #ssh #expect

#python #ssh #ожидать

Вопрос:

Я пытаюсь использовать expect для автоматизации задачи как часть более крупной программы на Python, и у меня возникают большие проблемы с получением стандартного вывода команды ssh, выполняемой на удаленном компьютере. Я не использовал expect раньше и не добился успеха в поиске решения на странице руководства.

Мне нужно использовать expect для автоматизации некоторых взаимодействий, прежде чем я смогу запустить эту команду, но я удалил их здесь, чтобы упростить вопрос.

Вот упрощенный пример программы:

 import subprocess

expect = """
/usr/bin/expect <<EOF

spawn ssh some_machine ls
expect eof
puts "$expect_out(buffer)"
"""

output = subprocess.check_output(expect, shell=True)
print(output)
  

Вывод:

 b'spawn ssh some_machine lsrn116029rnArchivernrn(buffer)n'
  

Похоже, что он содержит команду spawn, а также «(buffer)» в конце. Я не уверен, почему это происходит. Я пытаюсь получить только результаты ls .

Если я включу режим отладки в expect, я вижу, что expect_out(buffer) значение устанавливается на то, что я хотел бы вернуть, но puts это не отражает.

Вывод:

 expect version 5.45
argv[0] = /usr/bin/expect  argv[1] = -d
set argc 0
set argv0 "/usr/bin/expect"
set argv ""
executing commands from command file
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {1753}
expect: read eof
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "116029rnArchivern"
<wrong output as above>
  

Комментарии:

1. Почему вы используете expect здесь? Вы просто запускаете команду и считываете ее стандартный вывод. Вы могли бы просто запустить subprocess.check_output('ssh some_machine ls', shell=True) .

2. Я упростил скрипт для примера, но мне нужно использовать его для автоматизации некоторого взаимодействия, прежде чем я смогу получить выходные данные.

3. Кроме того, в вашем сценарии оболочки expect отсутствует терминал EOF , соответствующий <<EOF .

Ответ №1:

Вы можете отключить вывод журнала из expect с помощью log_user команды:

 log_user 0
spawn ssh some_host ls
expect eof
puts "$expect_out(buffer)"
  

Без log_user 0 я получаю:

 $ expect -f sample.tcl
spawn ssh some_host ls
file1
file2
  

Добавляя log_user 0 , я получаю:

 $ expect -f sample.tcl
file1
file2
  

Кажется, есть некоторая странность, когда вы отправляете expect скрипт через stdin, но, похоже, работает следующее:

 import subprocess
import tempfile

expect = """
log_user 0
spawn ssh some_host ls < /dev/null
expect eof
puts "$expect_out(buffer)"
"""

with tempfile.NamedTemporaryFile() as fd:
    fd.write(expect)
    fd.flush()
    fd.seek(0)
    output = subprocess.check_output(['expect', fd.name])

print(output)
  

Комментарии:

1. Единственный вывод, который я получаю от этого, это: b'(buffer)n'

2. В вашем комментарии чего-то не хватает, но я думаю, что вижу поведение, которое вы пытались описать. Взглянув…

3. Да, это действительно работает с использованием sample.tcl. Но когда я использую в python, он не работает должным образом, и выходные данные отображаются только выше. Я продолжу расследование…