оболочка динамически отвечает на запрос терминала - PullRequest
0 голосов
/ 10 мая 2018

questions.sh

#!/bin/bash

declare -a animals=("dog" "cat")
declare -a num=("1" "2" "3")

for a in "${animals[@]}"
do
    for n in "${num[@]}"
    do
        echo "$n $a ?"
        read REPLY
        echo "Your answer is: $REPLY"
    done
done

responseder.sh

#!/usr/bin/expect -f

set timeout -1

spawn ./questions.sh

while true {

    expect {
        "*dog*" { send -- "bark\r" }

        "^((?!dog).)*$" { send -- "mew\r" }
    }


}

expect eof

выполняется: './responder.sh'

ожидаемый результат:

1 dog ?
bark
Your answer is: bark
2 dog ?
bark
Your answer is: bark
3 dog ?
bark
Your answer is: bark
1 cat ?
mew
Your answer is: mew
2 cat ?
mew
Your answer is: mew
3 cat ?
mew
Your answer is: mew

фактический результат: завис на вопросе "кошка" и не отвечает ...

1 dog ?
bark
Your answer is: bark
2 dog ?
bark
Your answer is: bark
3 dog ?
bark
Your answer is: bark
1 cat ?

пробовал и искал несколько способов, но все еще не работал.Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

(Это не прямой ответ на ваш вопрос. Только к вашему сведению.)

Вы можете написать Ожидайте -подобные сценарии только с шелл-кодом.Например:

question.sh:

[STEP 109] # cat question.sh
declare -a animals=("dog" "cat")
declare -a num=("1" "2" "3")

for a in "${animals[@]}"
do
    for n in "${num[@]}"
    do
        echo "$n $a ?"
        read REPLY
        echo "Your answer is: $REPLY"
    done
done

responder.sh:

[STEP 110] # cat responder.sh
export SEXPECT_SOCKFILE=/tmp/qa.sock
sexpect spawn bash question.sh

while true; do
    sexpect expect -cstring -re '(dog|cat) [?][\r\n]+'
    ret=$?
    if [[ $ret == 0 ]]; then
        anim=$(sexpect expect_out -index 1)
        if [[ $anim == dog ]]; then
            sexpect send -cstring 'bark\r'
        else
            sexpect send -cstring 'meow\r'
        fi
    else
        if ! sexpect chkerr -errno $ret -is eof; then
            sexpect close
        fi
        sexpect wait
        break
    fi
done

Запустите его:

[STEP 111] # bash responder.sh
1 dog ?
bark
Your answer is: bark
2 dog ?
bark
Your answer is: bark
3 dog ?
bark
Your answer is: bark
1 cat ?
meow
Your answer is: meow
2 cat ?
meow
Your answer is: meow
3 cat ?
meow
Your answer is: meow
[STEP 112] #
0 голосов
/ 10 мая 2018

Ожидаемая программа зависает, потому что вы сопоставляете первую «собаку», посылаете лай, затем вы expect eof с бесконечным таймаутом.Конечно, у вас нет «eof», потому что сценарий оболочки ожидает ввода.

Вам нужно использовать команду exp_continue для своих циклов, а не while:

#!/usr/bin/expect -f
set timeout -1
spawn ./questions.sh
expect {
    -re {dog \?\r\n$}        { send -- "bark\r"; exp_continue }
    -re {(?!dog)\S+ \?\r\n$}  { send -- "mew\r";  exp_continue }
    eof
}

Я сделал шаблоны гораздо более конкретными: либо «собака», либо «не собака», за которыми следуют пробел, вопросительный знак и символы конца строки.

Команды exp_continue сохранят зацикливание кодав пределах команды ожидаемого до тех пор, пока не встретится «eof».


Мы можем сделать шаблон немного СУХИМ:

expect {
    -re {(\S+) \?\r\n$} { 
        if {$expect_out(1,string) eq "dog"} then {send "bark\r"} else {send "mew\r"} 
        exp_continue 
    }
    eof
}
...