Каким образом сценарий Expect определяет содержимое файла wait_out - PullRequest
1 голос
/ 02 апреля 2020

Я пытаюсь написать сценарий, который предоставит учетные данные для VPN с одним предупреждением, где VPN требует, чтобы я предоставил OTP.

Это мой сценарий:

#! /usr/bin/expect

set vpn    [ lindex $argv 0]
set group  [ lindex $argv 1]
set user   [ lindex $argv 2]
set secret [ lindex $argv 3]

log_user 2 
spawn nmcli con up $vpn --ask

expect {
        "GROUP:" { 
                send "$group\r"
                exp_continue
        }
        "Username:" { 
                send "$user\r"
                exp_continue
        }
        Password: {
                send_user "\nProvide RSA OTP:"
                expect_user -re ":(.*)\r"
                set otp $expect_out(0,string)  <--------- Error!!!
                set pass "$secret$otp"
                send "$pass\r"
                exp_continue
        }
        "Connection successfully activated" {
                send_user "Connected to VPN\r"
        }
        "Login failed" {
                send_user "Login failed\r"
                exp_continue
        }
        "already active" {
                send_user "Already connected to VPN\r"
        }
}
exit

Я включил стрелка к тому, что я думаю, является источником проблемы, потому что, когда я запускаю этот скрипт, он выглядит так, как ожидающий_ содержит Password:. Учитывая то, что я прочитал на странице руководства, я представил, что буфер очищается каждый раз, когда выполняется новое совпадение, и поэтому он содержит строку, совпадающую в последнем предложении ожидаемого (в данном случае expect_user -re ":(.*)\r"), однако, похоже, я ошибаюсь. Я не видел никаких заметок, в которых говорилось, что доступ к содержимому Ожидайте_пользователя нужно использовать с помощью другой функции, как interact, поэтому я не уверен, где мой пароль go?

Спасибо

1 Ответ

0 голосов
/ 02 апреля 2020

При использовании send_user вы не увидите эхо того, что вы пишете, в отличие от отправки в порожденную команду, поэтому вы никогда не совпадете с :, если пользователь не введет его явно. Кроме того, вы будете читать перевод строки, а не возврат каретки. Поэтому используйте

expect_user -re "(.*)\n"

для получения пользовательского ввода, а $expect_out(1,string) (1, а не 0) будет содержать ввод.

То, что вы наблюдаете, - это тайм-аут в вашем expect_user, который Вот почему переменная не обновляется и по-прежнему содержит старое совпадение.


Чтобы защитить себя от невидимых тайм-аутов, вы можете настроить «глобальную» проверку тайм-аута, начав с

proc abort { } { send_user "Timeout!" ; exit 2 }
expect_before timeout abort

expect_before выполняется "перед" каждым expect, но, кажется, перед каждым expect_user.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...