Как передать результат работы Expect в bash-скрипт

Имеется bash-скрипт, который выполняет внутри себя Expect.

Краткий смысл такой, на кроне висит bash-скрипт, который подключается по telnet к маршрутизатору, выполняет некоторую команду и результат этой команды нужно передать в виде переменной обратно в bash для последующего парсинга и обработки.

И я никак не пойму как из expect что-то передать в bash.

Набор команд expect выглядит так:

#!/bin/bash

#Команды для expect:
COMM="

#Время ожидание expect
set timeout 1

#Соединение ssh:
spawn telnet 192.168.1.1 23
expect \"*(yes/no)?*\" {send \"yes\r\"}
expect \"Login:\"
send \"$LOGIN\r\"
expect \"Password:\"
send \"$PASSWD\r\"

expect \"*>\"
send \"show interface ${interface_name}\r\"

#Результат этой команды надо вернуть в bash


#Завершение выполнения expect:
expect eof
"

Вызов expect делаю так:

expect -c "$COMM"

Ответы (2 шт):

Автор решения: Fat-Zer

Как-то так:

NET_INFO="$(expect <<EOF
  log_user 0
  spawn telnet 192.168.1.1 23
  # ...
  expect "Login:"
  send "$LOGIN\r"
  # ...
  send "show interface ${interface_name}\r"
  expect -re "(.*)\r\(.*\)>"
  send_user "\$expect_out(1,string)"
EOF)"

Ключевые моменты:

  • log_user 0 — подавить весь лишний вывод expect
  • expect -re "(.*)\r\(.*\)>" — ответ сопоставляется регулярному выражению. Первой группе (скобкам) сопоставляется ответ команды, а за ним идёт приглашение
  • expect_out(1,string) — переменная, в которой хранится то что сопоставила последняя команда expect. 1 говорит, что нам нужно то что сопоставлено первой группе регулярного выражения, а string — что нам нужен собственно текст. Подробности смотри в man expect.
  • send_user "\$expect_out(1,string)" — отправка в стандартный вывод данной строки. Внимание на то что \$ перед expect_out заэскейпен, дабы bash не пытался его интерпретировать т.к. это переменная самого expect.
  • NET_INFO="$(...)" — обычное присваивание вывода команды переменной.
  • expect <<EOF ... EOF — это встроенного документ, heredoc bash. К сути вопроса это не относится, но такой синтаксис делает скрипт куда более читаемым.
→ Ссылка
Автор решения: RiG

Решил вопрос, вот рабочий пример

COMMSHOW="

#Время ожидание expect
set timeout 1

#Соединение ssh:
spawn telnet 192.168.1.1 23
expect \"*(yes/no)?*\" {send \"yes\r\"}
expect \"Login:\"
send \"$LOGIN\r\"
expect \"Password:\"
send \"$PASSWD\r\"

#Выполняемые команды:

expect \"*>\"
send \"show interface ${interface_name}\r\"

expect \"*>\"
puts \"$expect_out(buffer)\"

send \"exit\r\"

#Завершение выполнения expect:
expect eof
"

Сам Expect вызываю так, в output лежит ответ

output=$(expect -c "$COMMSHOW")
→ Ссылка