嗨根据this post,unbuffer
通过伪终端(pty)连接到一个命令,这使得系统把它视为一个交互过程,因此不使用任何stdout缓冲。什么是Windows上的非缓冲程序的等价物?
我想在Windows上使用此功能。我可以知道在Windows上相当于unbuffer
程序吗?谢谢。
嗨根据this post,unbuffer
通过伪终端(pty)连接到一个命令,这使得系统把它视为一个交互过程,因此不使用任何stdout缓冲。什么是Windows上的非缓冲程序的等价物?
我想在Windows上使用此功能。我可以知道在Windows上相当于unbuffer
程序吗?谢谢。
您所描述的行为是使用运行时库进行I/O的应用程序的典型特征。默认情况下,大多数运行时库检查句柄是否是字符模式设备(如控制台),如果是,则不执行任何缓冲。 (理想情况下,运行时库会像处理控制台一样对待管道,但似乎大多数情况下不会)。
我不知道有任何明智的方法来欺骗这样的应用程序,使其思考它当它正在写入管道时正在写入控制台。
原则上,如果您知道需要多少数据,则可以使用console API functions为应用程序创建控制台以写入,然后从控制台读取输出。但是你不能从Java那里完成,你需要编写一个C应用程序来为你做。
类似地,原则上它应该可能写出一个相当于Unix伪终端的设备驱动程序,它像一个管道一样工作,但报告自己是字符模式设备。但是,编写设备驱动程序需要特定的专业知识,并且必须进行数字签名,因此除非现有产品存在,否则此方法不太可行。
一个现有选项可能是[com0com](http://com0com.sourceforge.net/)null-modem模拟器。(如果我没有记错,串口通常被视为无缓冲。) – 2017-10-07 07:31:59
我花了一些时间在这个,并成功。我在研究期间发现了这个博客,并决定返回并提供我的解决方案,以便为下一个人节省一些时间。我以虚假电子邮件的方式回应客人,所以我不会互动,但不需要进一步的信息。
在7月18日在'12 19:41哈利·约翰斯顿写道:
“原则上,如果你知道有多少数据预期,你可以使用控制台API函数来创建一个控制台应用程序编写然后从控制台读取输出,但是你不能从Java那里完成,你需要编写一个C应用程序来为你完成。“
事情是,已经有一个实用程序来做到这一点。它的用途略有不同,但它可以用来提供理想的结果。其预期目的是使Windows控制台应用程序能够与Linux风格的tty终端进行交互。它通过运行隐藏的控制台并直接访问控制台缓冲区来完成此操作。如果你试图使用它 - 你会失败。我很幸运,发现这个实用程序有没有文档的开关,这将允许它提供简单的无缓冲输出。如果没有这些开关,它会失败并显示错误 - 输出不是tty - 尝试输出管道时。
该实用程序被称为winpty。你可以在这里得到它:
https://github.com/rprichard/winpty/releases
未公开的开关都在这里提到:
https://github.com/rprichard/winpty/issues/103
我使用MSYS2版本。你需要使用msys-2.0.dll。
只需运行:
winpty.exe -Xallow-non-tty -Xplain your_program.exe | receive_unbuffered_output.exe
-Xallow-non-tty
,将使管道输出
-Xplain
,将删除添加的Linux终端转义码(或任何他们是所谓的)
所需的文件:
winpty.exe
winpty-agent.exe
winpty.dll
msys-2.0.dll
winpt y-debugserver.exe - 不需要
是的,它的工作原理,帮助解决了这个问题:https://stackoverflow.com/questions/46443544/python-popen-sdtout-doesnt-get-all-的 - 输出 - 当-EXE-失败 – 2017-10-01 08:59:12
声明:我的回答只处理使用MSVC编译的可执行文件。
缓冲策略在Microsoft C运行时(CRT)库内编码。您可以了解详细信息here。本文建议使用控制台句柄并操纵控制台缓冲区以接收无缓冲的输出。
然而,有Microsoft C运行时内无证功能继承文件与一些内部直接使用STARTUPINFO
结构的lpReserved2
和cbReserved2
领域其父进程的标志处理。您可以在Microsoft Visual Studio提供的crt源代码中找到详细信息。或者在GitHub上搜索类似posfhnd
的内容。
我们可以利用这个未公开的特性来提供一个管道句柄,并为子进程指定FOPEN | FDEV
标志来欺骗子进程,将这个管道的处理方式与FILE_TYPE_CHAR
句柄相同。
我有一个工作Python3 script来演示这种方法。
没有等价物。 Windows没有伪终端。 – 2012-07-17 22:46:19
@HarryJohnston嗨,哈利,我想用Java来执行外部命令并实时读取stdout输出。某些.exe程序因stdout缓冲而给我带来问题。程序仍在运行时,我无法获得任何stdout输出。当程序结束时,我突然得到很多标准输出。 (当我在命令提示符窗口中手动运行时,此程序能够生成实时标准输出)如果Windows中没有伪终端,我该如何解决此问题? – userpal 2012-07-18 04:04:43
缓冲区不是操作系统,而是应用程序。您需要修复有问题的.exe程序,以便它们不会缓冲它们的输出。 – 2012-07-18 04:16:50