我如何“获取”期望脚本

我如何“获取”期望脚本

我被迫使用如下脚本:

# test.sh
function my_fun
{
    echo "Give value for FOO"
    local my_var
    read my_var
    export FOO=$my_var
}

# Call my_fun function
my_fun

从我的外壳中获取它。

$ source test.sh
Give value for FOO
stackexchange
$ echo $FOO
stackexchange

我想使用 Expect 来自动化脚本,如下所示:

$ expect test.exp
$ echo $FOO
stackexchange

环境变量的数量和名称test.sh未知。

更新:

  • 将 my_fun 函数全部添加到 test.sh 中。

答案1

根本问题是子进程无法改变其父进程的环境。这就是为什么您需要source该 shell 脚本,以便环境变量将保留在您当前的 shell 中。

Expect 被设计用于spawn子进程。您当前的 shell不能受到 的结果的影响expect test.exp

但是,您可以生成一个 shell,获取该 shell 脚本,然后保留通过与它交互来外壳:这是我的想法,并且未经测试:

#!/usr/bin/expect -f
set timeout -1
spawn $env(SHELL)
set myprompt "some pattern that matches your prompt"
expect -re $myprompt
send "source test.sh\r"
expect {
    "Give value for " {
        # provide the same answer for every question:
        send "some value\r"
        exp_continue
    }
    -re $myprompt
}
interact

现在您正在与您生成的 shell 进行交互。当您使用exit该 shell 时,生成的 shell 会终止,然后期望脚本结束,然后您将返回到当前的 shell(没有初始化的变量)。

答案2

您可以创建一个 shell 脚本来区分运行该函数之前和之后的环境:

#!/bin/bash
# run.sh
source ./test.sh
ENV_BEFORE=$(set | grep -v "^_")
my_fun
ENV_AFTER=$(set | grep -v "^ENV_BEFORE" | grep -v "^_")
# echo the new environment variables
echo "$ENV_AFTER" | grep -v -F -x -f <(echo "$ENV_BEFORE")

然后使用expect运行该脚本:

# test.exp
log_user 0
spawn ./run.sh
expect "Give value for "
expect -re  "(.*)\r\n"
send -- "stackexchange\r\n"
expect -re  "(.*)\r\n"
expect -re  "(.*)\r\n"
puts $expect_out(1,string)

其输出的来源:

$ source <(expect test.exp)
$ echo $FOO
stackexchange

答案3

spawn /bin/bash -c ". ./source_script.sh && ./exec_script.sh"

相关内容