shell 动态响应终端提示

shell dynamically answer to terminal prompt

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

responder.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

实际结果:挂在 'cat' 问题上不回答...

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

尝试并搜索了多种方法,但仍然无效。非常感谢。

expect 程序挂起,因为您匹配第一个 "dog",发送 bark,然后您 expect eof 无限超时。当然你没有 "eof" 因为 shell 脚本正在等待输入。

您需要为循环使用 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
}

我使模式更加具体:"dog" 或 "not dog" 后跟 space、问号和行尾字符。

exp_continue 命令将使代码在 expect 命令中循环,直到遇到 "eof"。


我们可以让图案更干一点:

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