使用expect自动化交互的2个脚本

3

我有两个简单的脚本,需要使用第三个expect脚本自动互相交互。

script1.sh

#!/bin/bash

echo "s1: started"
echo "question1"
read
echo "got ${REPLY}"
echo "question2"
read
echo "got ${REPLY}"
echo "question3"
read
echo "got ${REPLY}"
echo "s1: finished"

script2.sh

#!/bin/bash

echo "s2: started"
read
echo "got ${REPLY}"
echo "answer1"
read
echo "got ${REPLY}"
echo "answer2"
read
echo "got ${REPLY}"
echo "answer3"
echo "s2: finished"

auto_s1_s2.exp

#!/usr/bin/expect

spawn -noecho ./script1.sh
set s1ID $spawn_id

spawn -noecho ./script2.sh
set s2ID $spawn_id

expect -i $s1ID "question1" {
    send_user "exp: question1\n"
    send -i $s2ID "question1\r"
    expect -i $s2ID "answer1" {
        send_user "exp: answer1\n"
        send -i $s1ID "answer1\r"
    }
}
interact

运行./auto_s1_s2.exp的输出如下:

s1: started
question1
exp: question1
question1
s2: started
got question1
answer1
exp: answer1


我希望您能翻译以下内容:

我期望s1会回应question1,并通过expect $s1ID "question1"进行验证,然后expect脚本将发送question1s2,并期望从中接收answer1,然后将answer发送到s1,如此循环。

Illustration here

看起来 answer1 没有被 script1 接收到。

我在这里做错了什么?


其他人无法从您的脚本中推断出您要做什么,因为它未按您的预期工作。您能否详细说明您的目的是什么? - pynexj
@pynexj 我添加了更多信息。 - Mahmoud Mahdi
1
script1 does get the answer1, but your interact command will not show it. You need to tell it to listen to the spawn id: interact -i $s1ID - meuh
Expect源代码中有一个示例程序,演示了两个国际象棋程序之间的对弈:https://core.tcl-lang.org/expect/artifact/57b2967d35be0a0d - glenn jackman
3个回答

1
这是一个完整的示例。

Shell部分:

[STEP 101] $ cat s1.sh
echo "s1: started"
echo "question1"
read
echo "got ${REPLY}"
echo "question2"
read
echo "got ${REPLY}"
echo "question3"
read
echo "got ${REPLY}"
echo "s1: finished"
[STEP 102] $ cat s2.sh
echo "s2: started"
read
echo "got ${REPLY}"
echo "answer1"
read
echo "got ${REPLY}"
echo "answer2"
read
echo "got ${REPLY}"
echo "answer3"
echo "s2: finished"
[STEP 103] $

预期部分:

[STEP 104] $ cat qa.exp
spawn bash s1.sh
set s1 $spawn_id

spawn bash s2.sh
set s2 $spawn_id

expect -i $s1 "s1: started"
expect -i $s2 "s2: started"

expect {
    -i $s1 -re "(question.)" {
        set q $expect_out(1,string)

        send -i $s2 "$q\r"
        expect -i $s2 -re "got\[^\r\n]+\[\r\n]+"
        expect -i $s2 -re "(\[^\r\n]+)\[\r\n]+$"
        set a $expect_out(1,string)

        send -i $s1 "$a\r"

        exp_continue
    }
    -i $s1 eof {
        exp_continue
    }
    -i $s2 eof {
    }
}

结果:

[STEP 105] $ expect qa.exp
spawn bash s1.sh
spawn bash s2.sh
s1: started
question1
s2: started
question1
got question1
answer1
answer1
got answer1
question2
question2
got question2
answer2
answer2
got answer2
question3
question3
got question3
answer3
s2: finished
s2: finished
got s2: finished
s1: finished
[STEP 106] $

你的答案得出了正确的结果,但我无法理解这里正则表达式的行为。 - Mahmoud Mahdi
1
expect -d qa.exp 可以提供详细信息。 - pynexj

1
给你一个例子,包含sexpect
[bash] # cat qa.sh
sock1=/tmp/s1.$$.sock
sock2=/tmp/s2.$$.sock

sexpect -s $sock1 spawn bash s1.sh
sexpect -s $sock1 expect 's1: started'

sexpect -s $sock2 spawn bash s2.sh
sexpect -s $sock2 expect 's2: started'

while true; do
    sexpect -s $sock1 expect -re '(question.)'
    ret=$?
    if sexpect chkerr -err $ret -is eof; then
        break
    fi
    q=$( sexpect -s $sock1 expect_out -i 1 )

    sexpect -s $sock2 send -cr "$q"
    sexpect -s $sock2 expect -re $'got[^\r\n]+[\r\n]+'
    sexpect -s $sock2 expect -re $'([^\r\n]+)[\r\n]+$'
    a=$( sexpect -s $sock2 expect_out -i 1 )

    sexpect -s $sock1 send -cr "$a"
done

sexpect -s $sock1 wait
sexpect -s $sock2 wait
[bash] #

结果:

[bash] # bash qa.sh
s1: started
s2: started
question1
question1
got question1
answer1
answer1
got answer1
question2
question2
got question2
answer2
answer2
got answer2
question3
question3
got question3
answer3
s2: finished
s2: finished
got s2: finished
s1: finished
[bash] #

0

meuh所提到的在他的评论中,expect脚本运行良好,但由于interact未监听到特定的spawn_id而未显示输出


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接