【问题标题】:How can piping tail of a log to a script cause the process generating the log to stop generating entries?将日志的尾部管道传输到脚本如何导致生成日志的进程停止生成条目?
【发布时间】:2020-04-03 20:58:22
【问题描述】:

我正在尝试解决一个奇怪的问题。我有证据表明我将尾部输出传送到的脚本是问题的原因,但我不确定要查找什么。这是我得到的:

我有一个 java 程序,它生成一个到 stdout 的日志,我与它合并 stderr (2>&1) 并重定向到一个文件。我运行了一个单独的 shell 脚本,它执行一个 tail -F 将它通过管道传递给一个 Perl 脚本,该脚本对日志中的事件进行操作并且永远不会退出。

这不是最好的设计,但直到最近(过去几个月),一切都已经奏效多年。 jar 文件有一个明显的问题,因为日志已经积累了大量的错误,所以作为第一步,我更新到了最新版本。然而,在我上面描述的设置中,新版本停止向日志添加条目。

为了缩小问题的范围,我做了以下工作:

tail -F log | perl -pne ‘$|=1;’
tail -F log

这表明输出继续流动,并表明脚本正在执行的某些操作导致了问题。

但是,这似乎不是全部,因为当我在另一台计算机上运行所有内容时,那里的所有内容都可以正常工作!仅在 jar 停止打印到日志的特定计算机上。

其他细节:

  • java 进程在所有情况下都会继续运行。
  • 在后台运行所有内容后,我正在通过 tail -F 再次进行测试
  • 可能是操作系统更新导致了该问题
  • 在 bash shell 中运行
  • 我将 perl 脚本使用的模块更新为相同的模块,但它工作的计算机与停止 java 输出的计算机之间显然存在细微差别,我尚未调查
  • 以下是我用于测试的实际命令:
java -cp WemoServer.jar mpp.wemo.server.Headless -p 4033 -upnp -run -log >> WemoServer.log 2>&1 &
sh -c "tail -F WemoServer.log | ./WemoServerLogProcessor.pl -r rules.txt --extended" 2>&1 >> WemoParser.log &

#And I'm testing whether the java process stops generating output via:
tail -F WemoServer.log

我不知道如何调试这个问题。我应该寻找什么?

更新:我了解到 java 进程仍然可以写入日志。我知道这一点,因为如果我让它运行足够长的时间,并且初始 bonjour 搜索功能完成并在日志中写入一条说明尽可能多的消息。

但是,当我将日志的尾部通过管道传输到脚本时,似乎事件会尝试停止,例如在插座打开或关闭或检测到运动时写入。如果我不将日志的尾部通过管道传输到我的 Perl 脚本,那么所有设备事件都会在发生时写入日志。就好像java进程失去了与设备的通信能力。

我知道 bonjour 用于发现设备并将其 IP 地址打印到日志中,所以我不知道中断可能是什么。我的 Perl 脚本绝对不会对端口或 bonjour 或任何东西做任何事情。它只是在 STDIN 上解析一个文件。

我想我可以尝试更新操作系统,因为它比我的笔记本电脑落后 2 个版本,但我想了解发生了什么。

【问题讨论】:

  • 您在其他进程运行时是否看到 tail -F WemoServer.log 的任何输出?为什么不只使用 tail -F WemoServer.log | ./WemoServerLogProcessor.pl -r rules.txt --extended 2>&1 >> WemoParser.log ?如果您只运行 tail -F WemoServer.log | ./WemoServerLogProcessor.pl -r rules.txt --extended 2>&1 >> WemoParser.log 在单独的终端中,您应该会看到一些输出——它是您的调试工具。此时我只能假设您的 WemoServerLogProcessor.pl 可能已经缓存了输出——直到缓冲区未满才会有任何输出。
  • 我不明白你的评论。我不关心我的 Perl 脚本的输出。停止的是 Java 进程的输出。我的 Perl 脚本处理 JavaScript 生成的所有内容,直到我运行 Perl 脚本,但在那之后,Java 进程不再有任何输出进入我的 Perl 脚本。
  • 关于 sh 包装的命令,我一直在测试没有它。实际上,在过去的几年里,我一直在登录脚本中运行这两个命令,每个命令前面都有 nohup,我想我添加了 sh 包装,因为登录脚本从未退出(我怀疑这是由于一个文件句柄,包装在sh 中解决了它)。然而,这与我的问题无关。无论我在没有sh 的情况下运行它,还是在每种情况下运行第二个命令时,java 进程都会停止打印到 WemoServer.log(仅在一台计算机上)。
  • 嗯,您在回答中指的是 JavaScript——从您的帖子中我只看到 javaperl。不幸的是,我无法在 Java 方面提供帮助 - 如果 Java 产生到 STDOUT/STDERR 的输出,那么我看不到 perl 脚本的管道如何影响它。
  • 对不起。我的手机将 java 自动更正为“JavaScript”。我已将其固定在一个地方。错过了另一个。我也不明白 java 进程的输出会如何受到影响。这很奇怪。

标签: java perl io bonjour


【解决方案1】:

我问错了问题。是的,输出正在停止,但是输出的停止恰好是通过连接到输出流来催化的。即使不理会,输出的结束最终也会发生。

它停止的真正原因是因为我有 2 个单独的 WeMo 设备订阅,它只支持 1 个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-05
    • 2018-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    相关资源
    最近更新 更多