为啥 IO::Pty 和 Expect 模块可以帮助解决 open2 的障碍?

Posted

技术标签:

【中文标题】为啥 IO::Pty 和 Expect 模块可以帮助解决 open2 的障碍?【英文标题】:why IO::Pty and Expect modules can help to solute open2 's block?为什么 IO::Pty 和 Expect 模块可以帮助解决 open2 的障碍? 【发布时间】:2012-10-03 09:23:10 【问题描述】:

perl 的 open2 perldoc : http://perldoc.perl.org/IPC/Open2.html 描述:

他的整个事情很危险,因为你可能会永远阻止。它假设它会与 bc 之类的东西交谈.... ... CPAN 的 IO::Pty 和 Expect 模块可以帮助解决这个问题,因为它们提供了一个真正的 tty(实际上是一个伪 tty),它可以让您再次回到调用命令中的行缓冲。

但我不明白为什么 IO::Pty 和 except 模块可以解决 open2 的问题?

顺便问一下,open2返回的FileHandler是否可以无阻塞读取?

非常感谢!

【问题讨论】:

【参考方案1】:

当您使用缓冲 I/O 时,数据不会通过文件句柄发送,直到缓冲区已满。这与终端 I/O 不同,终端 I/O 一旦用户按下 Enter 键就会发送一行。因此,如果您正在编写一个程序以像用户一样与程序进行交互,缓冲 I/O 可能会导致问题。例如,您的程序可以发送一行数据,期望对方收到并输出回复。但是,如果在您等待回复时该行数据仍在输出缓冲区中,您将死锁 - 您的程序正在等待来自仍在等待您的输入的程序的回复,该程序仍在输出缓冲区中。

使用 pty 与程序交互允许您使用行缓冲(在两个方向上),以便在流中遇到换行符时发送数据。

此外,可以以非阻塞方式读取任何文件句柄 - 只需使用 select 确定该文件句柄上是否有可用数据。

这篇文章可能有助于解释事情:http://www.pixelbeat.org/programming/stdio_buffering/

【讨论】:

好的,非常感谢!但是当我使用 pipe() 函数创建管道时,我发现每次在 INPUT 端写入一行,OUTPUT 端就会立即读取该行,这是否意味着管道也在行缓冲? 缓冲发生在 stdio 级别(通过文件句柄访问内容),而不是文件描述符级别。为了解释您所看到的,我必须查看您的代码。 父进程打开一个文件,然后fork一个子进程,子进程和父进程共享文件的stdio级缓冲区吗? 没有。子缓冲区将是分叉时父缓冲区的副本,但它们将是独立的缓冲区。但是,我的实验表明它们共享相同的文件描述符。因此,如果一个进程从文件中读取,它将影响另一个进程在读取文件句柄时看到的内容。

以上是关于为啥 IO::Pty 和 Expect 模块可以帮助解决 open2 的障碍?的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能导入 random模块,求解

在 WebdriverIO 中,为啥 `expect` 行需要在其前面加上 `await` 才能正确测试某些内容?

expect基本使用方法

错误:找不到模块 'jasmine-expect' [量角器]

自动化shell脚本except与python的pexpect模块

为啥不能帮小海龟