“Interact”在 bash/expect 脚本中未按预期工作

“Interact”在 bash/expect 脚本中未按预期工作

为了配置嵌入式设备(即将映像写入闪存),必须在启动阶段输入一系列众所周知的命令。该算法类似于:

  • 在启动期间输入任意键捕获引导加载程序 shell
  • 闪光图像A
  • 闪光图像B
  • ...
  • 继续启动(使用新映像)

由于我们必须首先在启动过程中的某个时刻捕获引导加载程序 shell,我认为应用expect脚本可以很好地解决这个问题。我想要混合一些其他的 bash 命令来实现关于连接到哪个设备节点等的逻辑。我想到的是(仅预期部分)如下:

#!/bin/bash
DEVICE=...
FLASH_CMD_A=...
#Other bash stuff

expect <<SCRIPT
    set timeout 5
    spawn plink -serial -sercfg 115200,8,n,1 $DEVICE 

    expect "Hit any key to stop autoboot"
        sleep 1
        send "\r"

    expect "=>"
        sleep 1
        send "$FLASH_CMD_A\n"

    interact   
SCRIPT

echo "Done!"

我观察到的是:第一条期望行被正确捕获,睡眠正在工作,并且换行符似乎正在被发送。下一个期望(捕获提示)及其相应的睡眠似乎也正在工作。发送命令($FLASH_CMD_A)被打印到终端,单词之间有很多空格,但它似乎也有效。

最大的问题是他们interact似乎没有做任何事情。一旦执行第二个期望/发送,我就会回到 bash shell,甚至从未见过“完成!”打印到标准输出。我还尝试了交互语法:

interact {
    "=>"{
        send "\r"
        exp_continue
    }
}

但这没有用根本不。提示从未被捕获,脚本立即退出,就好像该interact语句根本不存在一样。关于我可能做错了什么有什么想法吗?我有:

expect -v
expect version 5.45

虽然命令似乎我无法确定是否会传递到设备。一旦我返回到 bash shell,设备遵循这些命令的所有输出都会丢失。但是,如果我第二次运行脚本,expect 似乎会转储其文本缓冲区(expect_out?)并立即退出。有趣的是,我期望之前发送的命令的输出包含在这个缓冲区转储中。

顺便说一句:我在虚拟机环境中尝试了相同的脚本,但没有捕获任何“预期”语句;所有输入都被打印到标准输出并通过。

答案1

作为解决方法,从文件运行 Expect 脚本,而不是通过标准输入:

#!/bin/sh

BLAH='echo hi'

ESCRIPT=`mktemp runner.XXXXXXXXXX` || exit 1

# nope
#expect -d - <<SCRIPT
cat >$ESCRIPT <<SCRIPT
  set timeout 5
  spawn $SHELL
  # FIXME whatever your prompt looks like
  expect -ex "% "
  send -raw "\r"
  expect -ex "% "
  send -- "$BLAH\n"
  expect -ex "% "
  interact
SCRIPT

expect -d $ESCRIPT

echo alas poor $SHELL I knew him well a man of infinit

# and probably also `trap` in the event this code gets whapped with an INT
# or something...
rm $ESCRIPT

相关内容