我编写了一个可以在带有某种形式的redhat操作系统的linux机器上运行16或20个小时的程序。如果我用nohup启动它或将输出重定向到文件,它运行正常,但是当用户启动它,将其发送到后台并注销时,它会在尝试发送简单状态消息时失败(报告该数字)文件导致的文件)。它抛出一个异常,大概是因为流不再有效。
一旦我们意识到它为什么对我起作用,但对他不起作用,我就进行了一些测试,并发现与Python,Bash和perl相比,ruby在这种行为中是独一无二的。
在这种情况下,ruby是否有充分的理由与其他脚本语言不同?有没有办法改变它,就像其他人一样?
我很确定C ++(和C)并不关心最终用户是否可以看到他们的消息输出 - 但我没有为这些语言编写测试。我很惊讶地发现,一旦你退出,发送到后台的工作就不会消失!所以,我当然从未测试过这种行为。
答案 0 :(得分:0)
如果你去后台,我相信试图写入stdout的任何语言的每个程序都应该得到错误代码。在C的情况下,您将获得一些返回值,您可能会忽略它。在其他语言中,我真的很惊讶,如果真的只有红宝石抛出异常。毕竟,这是os如何制作的,问题在于内核。我在perl中编写了一个守护进程,我确信我必须实现stdout,stderr和stdin关闭并且双重分叉才能在没有nohup的情况下被杀死。您不应该依赖于未记录的功能,要么依赖nohup为您完成,要么正确关闭输入和输出描述符。或者使用低级别的公开呼叫将它们重新打开到日志文件。
您是否尝试过使用其他语言重定向到脚本或从脚本重定向?当program1 |时,断管通常是错误的program2匿名管道的一端关闭,另一端请求读取/写入。
答案 1 :(得分:0)
当您注销时,$ stderr和$ stdout的接收者进程将被终止。您的$ stderr和$ stdout文件描述符现在连接到损坏的管道。当你写信给他们时,你应该从操作系统获得SIGPIPE。
你对C ++和C没有关心是错的。它与实现语言无关,或与“用户”是否可以“看到”输出无关。这是关于文件描述符是否仍然有效。由于另一端已经关闭,因此不再存在。
看一下用C或C ++编写的守护进程。注意它在fork之后和exec之前如何关闭子进程中的stderr和stdout。这就是它如何保护自己不会写入损坏的管道并通过操作系统发送SIGPIPE。