【发布时间】: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——从您的帖子中我只看到 java 和 perl。不幸的是,我无法在 Java 方面提供帮助 - 如果 Java 产生到 STDOUT/STDERR 的输出,那么我看不到 perl 脚本的管道如何影响它。
-
对不起。我的手机将 java 自动更正为“JavaScript”。我已将其固定在一个地方。错过了另一个。我也不明白 java 进程的输出会如何受到影响。这很奇怪。