ожидать, взаимодействовать, а затем снова ожидать

Есть несколько сообщений об одном и том же, но я все еще не могу заставить свой сценарий ожидания работать правильно. Я намерен автоматизировать все, но оставить ввод пароля для пользователя. Итак, есть 3 части сценария:

  1. автоматический вход
  2. дать пользователю возможность ввести пароль
  3. вернуть управление сценарию Expect для продолжения работы

Итак, у меня есть скрипт, который будет создан и имеет 3 команды чтения. Первый и последний должны быть заполнены Expect, а второй я хотел бы ввести сам:

#!/bin/ksh
read user?User:
echo "Expect entered the username $user"
read pass?Password:
echo "User entered the password $pass"
read command?"Shell>"
echo "Expect entered the command $command"

Мой сценарий ожидания:

#!/usr/bin/expect
spawn ./some_script
expect User
send I-am-expect\r
expect Password
interact
expect Shell
send I-am-expect-again

К сожалению, после того, как я ввел пароль, скрипт не продолжил работу и остался в режиме взаимодействия:

[root@localhost ~]# ./my-expect
spawn ./some_script
User:I-am-expect
Expect entered the username I-am-expect
Password:i am user
User entered the password i am user
Shell>

И, наконец, когда я ввожу что-то в «Shell» и нажимаю [ENTER], ожидайте выхода с ошибкой:

Expect entered the command
expect: spawn id exp4 not open
    while executing
"expect Shell"
    (file "./my-expect" line 7)
[root@localhost ~]#

Я ценю любое объяснение или решение этой проблемы. Я использую ожидание версии 5.45


person Petras L    schedule 22.11.2015    source источник


Ответы (2)


Вы можете прочитать (expect_user) пароль пользователя самостоятельно, а затем send передать его в созданную программу. Например:

[STEP 101] # cat foo.exp
proc expect_prompt {} \
{
    global spawn_id
    expect -re {bash-[.0-9]+(#|\$)}
}

spawn ssh -t 127.0.0.1 bash --noprofile --norc
expect "password: "

stty -echo
expect_user -timeout 3600 -re "(.*)\[\r\n]"
stty echo
send "$expect_out(1,string)\r"

expect_prompt
send "exit\r"
expect eof
[STEP 102] # expect foo.exp
spawn ssh -t 127.0.0.1 bash --noprofile --norc
[email protected]'s password:
bash-4.3# exit
exit
Connection to 127.0.0.1 closed.
[STEP 103] #
person pynexj    schedule 24.11.2015
comment
Я замечаю то, что кажется побегом для одной квадратной скобки, но не для другой. Это намеренно? (наполовину вниз) \[\r\n]" - person Ari; 06.02.2019
comment
Открытая скобка особенная (tcl.tk/man/tcl8.6/ TclCmd/Tcl.htm#M11), а закрывающая скобка — нет. Не было бы ничего плохого в том, чтобы избежать закрывающей скобки, но это не является строго необходимым. - person glenn jackman; 07.02.2019

interact следует указывать с надлежащим условием для критериев выхода.

Следующий скрипт будет выполнять пользовательские команды в оболочке

exeCmds.sh

#!/bin/bash
read -p "User: " user
echo "Expect entered the username $user"
read -p "Password: " pass
echo "User entered the password $pass"
while :
do
        # Simply executing the user inputs in the shell
        read -p "Shell> " command
        $command
done

automateCmdsExec.exp

#!/usr/bin/expect 
spawn ./exeCmds.sh
expect User
send dinesh\r
expect Password
send welcome!2E\r
expect Shell>
puts "\nUser can interact now..."
puts -nonewline "Type 'proceed' for the script to take over\nShell> "
while 1 {
        interact "proceed" {puts "User interaction completed.";break}
}
puts "Script take over the control now.."

# Now, sending 'whoami' command from script to shell
send "whoami\r"
expect Shell>

# Your further code here...

Сценарий automateCmdsExec.exp удовлетворит потребности входа в систему сценария bash, и когда появится приглашение, он передаст управление пользователю.

Мы должны определить критерии выхода для interact, для которых я использовал слово proceed. (Вы можете изменить его в соответствии с вашими потребностями).

Однажды interact совпало со словом proceed. он вернет управление обратно ожидаемому сценарию.

Для демонстрационных целей я оставил еще одну пару команд send-expect.

i.e.

send "whoami\r"
expect Shell>

Вы можете оставить свой дальнейший код ниже interact, чтобы он мог выполняться скриптом.

person Dinesh    schedule 23.11.2015
comment
Да, но я хотел бы дать управление ожидать сразу после ввода пароля. Сразу после нажатия клавиши Enter. В исходном сценарии у меня нет возможности ввести что-то вроде «Продолжить» или перейти к передаче управления обратно, чтобы ожидать. Сценарий, который я предоставил, является просто примером/симулятором оболочки, с которой я пытаюсь общаться. Основная идея состоит в том, чтобы позволить пользователю ввести только пароль и ожидать, что он сделает все остальное. Я не хочу жестко задавать пароль в скрипте или передавать его через аргументы. - person Petras L; 23.11.2015
comment
@PetrasL У меня похожая потребность. Ты наконец-то понял, что делать? - person Stéphane Gourichon; 06.05.2020
comment
@PetrasL Мы будем очень признательны, если вы сможете завершить свой вопрос, либо обновив свой вопрос, либо добавив комментарий к ответу, который вы приняли, поскольку приведенные здесь ответы не дают точного ответа на ваш вопрос. - person Salam; 29.07.2020