使用Perl和Expect并将其管道输出到文件

3

我对Perl比较新,并一直在搜索与我尝试的内容相关的文档。但是我没有找到任何有用的信息。

我有一个程序,可以在stdout输出信息并在其中插入提示符。我需要编写一个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");

对于这种情况,用户只需按“Enter”一次即可。该程序小巧且非常快速——2秒足以达到第一个提示。

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

有人有什么建议,我如何获取第二部分内容?

更新: 我已经通过使用简单的脚本验证了Expect可以工作:

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

其中"< Return >"是Perl脚本可以查找的冗长表达式。

注意:我尝试编写了一个期望"< Return >"的Perl脚本...但没有任何区别。

即。

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

有什么想法吗?

更新2:

哇!我意外地找到了解决问题的方法。

所以,我在一些测试代码中犯了一个错别字...

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

请注意末尾的expect(2)...我不小心留下了它,但它却奏效了!
因此,我试图理解发生了什么。Unix的expect似乎不起作用!看起来Perl中实现的Expect“期望”任何东西...不仅仅是提示?
所以,我给expect提供了另外2秒钟来收集stdout,然后我就能得到所有的东西。
如果有人能够提供更详细的信息,让我了解这里发生了什么,我会很感激的。

1
你确定需要使用Expect吗?特别是当你刚开始学习Perl时,它似乎有些过头了。 - TLP
有其他建议吗?除了这个问题之外,我没有遇到任何看起来太复杂的事情。 - Rico
2个回答

4
尝试发送\r而不是\n - 你正在尝试模拟回车,而不是换行,tty设置可能无法转换它们。
另外:
来自Expect文档FAQ部分的建议,考虑到您的意外解决方案似乎很有可能:
我的脚本有时会无缘无故地失败。看起来我有时会失去从生成的程序输出的内容。
你可能退出得太快了,没有给生成的程序足够的时间来完成。尝试添加$exp->soft_close()以优雅地终止程序或对'eof'进行expect()。
或者,在你spawn()程序之后加上'sleep 1'。这可能是因为你的系统上的pty创建速度很慢(但如果你使用最新的IO-Tty,这是相当不可能的)。
标准的unix/tcl expect在交互模式下不会退出,这可能会给你的程序足够的时间来完成运行。

谢谢您的建议,但\r并不能解决问题。当我第一次发布这个问题时,我想我已经尝试过了,但不能确定。 - Rico
你知道如何在程序中提示并读取输入吗?当在你的脚本下执行时,它是否一直挂起?你可以通过使用strace跟踪程序来诊断更多正在发生的情况,看看它是如何尝试读取按键的。 - evil otto
我已经编写了接口。它使用以下代码:std::cin.clear(); std::cin.ignore(std::numeric_limitsstd::streamsize::max(), '\n'); - Rico
顺便提一下:我已经验证了“program”提示不是问题,因为我可以通过Unix接口使用expect,一切都正常。这是我在Perl中实现的方式有问题。也许这是一个Perl的bug? - Rico
我喜欢它!非常酷。我从没想过这会是我的问题。非常感谢,evil otto。 - Rico

1

我已经有一段时间没有使用Expect了,但我相信您需要提供一些内容让Expect与提示匹配:

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

例如。


匹配不是必需的,它是可选的。如果省略它,expect将等待2秒钟然后继续执行。 - Rico

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