【问题标题】:Using Expect with Perl and pipe to a file将 Expect 与 Perl 一起使用并通过管道传输到文件
【发布时间】:2011-07-20 05:10:06
【问题描述】:

我对 Perl 还很陌生,并且一直在互联网上搜索我正在尝试做的事情的文档。我运气不好。

我有一个程序可以将信息输出到标准输出,并带有提示。我需要制作一个 Perl 脚本来将该信息通过管道传输到文件中。

我以为我可以使用 Expect,但第一次提示后管道似乎有问题。

这是我的代码的一部分:

# Run program and compare the output to the BASE file
$cmd = "./program arg1 arg2 arg3 arg4 > $outfile";

my $exp = new Expect;
$exp->spawn($cmd);
BAIL_OUT("couldn't create expect object") if (! defined $exp);

$exp->expect(2);
$exp->send("\n");

在这种情况下,只有一个提示让用户按下“回车”。这个程序很小而且速度很快 - 2 秒就足以到达第一个提示。

输出文件只包含前半部分信息。

有人对我如何抓住下半场有任何建议吗?

更新: 我已经通过使用一个简单的脚本验证了这适用于 Expect:

spawn ./program arg1 arg2 arg3 arg4
expect "<Return>"
send "\r"
interact

其中“”是 Perl 脚本可以查找的详细表达式。

注意:我已经尝试编写我的 Perl 脚本来期待“”......这没有区别。

$exp->expect(2, '-re', "<Return>")

有什么想法吗?

更新2:

哈扎!我找到了解决问题的方法……完全是偶然的。

所以,我写的一些测试代码打错了……

$exp->expect(2);
$exp->send("\r");
$exp->expect(2);

注意尾随的 expect(2)...我不小心把它留在里面了,它起作用了!

所以,我试图了解正在发生的事情。 Unix expect 似乎不能这样工作!看来在 Perl 中实现的 Expect “期望”任何东西......不仅仅是提示?

所以,我提供了另外 2 秒的时间来收集标准输出,我能够得到所有东西。

如果有人可以提供一些关于这里发生的事情的更详细信息,我很想了解发生了什么。

【问题讨论】:

  • 您确定需要使用 Expect 吗?这似乎有点矫枉过正,尤其是当您是 perl 新手时。
  • 还有其他建议吗?除了这个问题,我没有遇到任何看起来太复杂的问题。

标签: perl expect


【解决方案1】:

尝试发送\r 而不是\n - 您正在尝试模拟回车,而不是换行符,并且 tty 设置可能无法翻译它们。

还有:

Expect docs FAQ 部分的建议,这似乎是您的意外解决方案:

我的脚本有时会在没有任何明显原因的情况下失败。它 似乎我有时会丢失衍生程序的输出。

您可能退出太快而没有给出生成的程序 有足够的时间完成。尝试添加 $exp->soft_close() 来终止 优雅地编程或为'eof'做一个expect()。

或者,尝试在 spawn() 程序之后添加“睡眠 1”。 可能是您系统上的 pty 创建速度很慢(但这是 如果您使用的是最新的 IO-Tty,则不太可能)。

标准 unix/tcl expect 不会以交互模式退出,这可能会给您的程序足够的时间来完成运行。

【讨论】:

  • 感谢您的建议,但 \r 并不能解决问题。当我第一次发布这个问题时,我想我已经尝试过了,但不能确定。
  • 你知道“程序”是如何提示和读取输入的吗?在你的脚本下执行时它只是挂起吗?您可以通过strace-ing 程序来诊断更多的情况,看看它是如何尝试读取按键的。
  • 我已经在那里写了接口。它使用以下代码:std::cin.clear(); std::cin.ignore(std::numeric_limits<:streamsize>::max(), '\n');
  • 事后思考:我已经验证“程序”提示不是问题,因为我可以通过 Unix 界面使用 expect 并且一切正常。这是我在 Perl 中实现它的方式的问题。也许这是一个 Perl 错误?
  • 我喜欢!很酷。我不知道这会是我的问题。非常感谢你,邪恶的奥托。
【解决方案2】:

自从我使用 Expect 已经有一段时间了,但我很确定您需要为 Expect 提供一些东西来匹配提示:

$exp->expect( 2, 'Press enter' );

例如。

【讨论】:

  • 匹配不是必需的,它是可选的。通过忽略它,期望将等待 2 秒然后继续。
猜你喜欢
  • 1970-01-01
  • 2016-02-26
  • 2016-06-11
  • 1970-01-01
  • 2017-08-09
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多