为什么ruby在写入std::error或std::out时,会话已经消失了



我编写了一个程序,它可以在带有某种形式的redhat操作系统的linux机器上运行16或20个小时。如果我启动它时不使用任何up或将输出重定向到一个文件,它会运行良好,但是当用户启动它,将它发送到后台并注销时,当它试图发送一个简单的状态消息(报告该文件产生的文件数量)时,它将失败。它抛出一个异常,可能是因为流不再有效。

当我们意识到为什么它对我有效而对他无效时,我进行了一些测试,发现与Python、Bash和perl相比,ruby在这种行为上是独一无二的。

在这种情况下,ruby的行为与其他脚本语言不同是否有一个很好的理由?有没有一种方法可以改变它,使其表现得像其他的?

我很确定c++(和C)并不关心最终用户是否可以看到它们的消息输出——但是我没有为这些语言编写测试。我很惊讶地发现,发送到后台的工作并没有在你注销后消失!所以,我过去肯定没有测试过这种行为。

如果你去后台,我相信任何语言的程序试图写标准输出应该得到错误代码。在C的情况下,您将获得一些返回值,您可能会忽略它。在其他语言中,如果真的只有ruby抛出异常,我会感到非常惊讶。毕竟,这是os的制作方式,问题在于内核。我用perl写了一个守护进程,我确信我必须实现标准输出,标准输出和标准输出关闭和双分叉,以免被杀死。您不应该依赖于未记录的特性,也不应该依赖于nohup来为您完成这些工作,或者正确地关闭输入和输出描述符。或者使用低级打开调用将它们重新打开到日志文件。

您是否尝试过用其他语言重定向到或从您的脚本?

当program1 | program2匿名管道的一端关闭,而另一端请求从它读取/写入时,管道破裂通常是错误的。

当您注销时,接收$stderr和$stdout的进程将被终止。您的$stderr和$stdout文件描述符现在连接到一个损坏的管道。当你写的时候,你应该从操作系统得到SIGPIPE。

你错了,c++和C不关心。它与实现语言无关,也与"用户"是否可以"看到"输出无关。它是关于文件描述符是否仍然有效。既然另一端已经关闭,它就不再是了。

看看用C或c++编写的守护进程。注意它是如何在fork之后和exec之前关闭子进程中的stderr和stdout的。这就是它如何保护自己不写入损坏的管道并被操作系统发送SIGPIPE。

最新更新