2

我有以下 bash 脚本(script.sh):

#!/bin/bash
read -p "Remove? (y|n): " answer
echo "You answered '$answer'."

我想用expect来驱动它。我有以下脚本(expect.exp,在同一目录中):

#!/usr/bin/expect -f
set timeout -1
spawn -noecho ./script.sh
expect "^Remove"
send "y\r"

但它没有按预期工作(双关语)。结果是:

~/Playground$ ./expect.exp 
Remove? (y|n): ~/Playground$

因此,expect 脚本在第一个 'expect "^Remove"' 行以某种方式失败并立即退出,并且 script.sh 的其余部分不执行。我在这里做错了什么?我一直在关注在线找到的基本教程(带有 ftp 示例的教程)。我在 Kubuntu 12.10 上使用 expect 5.45。

编辑 因此,如果我在最后添加“交互”或“期望 eof”,它会改变。但我不知道会发生什么以及为什么。有什么帮助吗?

4

2 回答 2

3

我看到两件事:

  1. "^Remove"是一个正则表达式,但默认expect使用 glob 模式。尝试

    expect -re "^Remove"
    
  2. 在开发程序时,添加exp_internal 1到脚本的顶部。然后 expect 会告诉你发生了什么。


啊,我看到 expect 为^超越Tcl 的 glob 模式添加了特殊的含义。

但是,因为 expect 不是面向行的,所以这些字符 (^$) 匹配当前在 expect 匹配缓冲区中的数据的开头和结尾(而不是行)

所以你看到的是你发送y\r然后你期望脚本退出,因为它没有更多的事情要做。当您的脚本退出时,生成的子进程将被杀死。因此需要等待生成的孩子首先结束:expect eof

于 2013-05-09T10:35:58.317 回答
0

问题

在 shell 脚本提示后,您没有匹配任何文本,因此您生成的进程的缓冲区永远不会被打印。脚本完成,生成的过程关闭,这就是故事的结尾。

解决方案

确保你expect有一个特定的响应或你的 shell 脚本的 EOF,然后打印你的缓冲区。例如:

#!/usr/bin/expect -f

spawn -noecho   "./script.sh"
expect "Remove" { send "y\r" }
expect EOF      { send_user $expect_out(buffer) }
于 2013-05-09T13:53:25.907 回答