我有一个Java程序,我在Mac OS X上使用Bash脚本运行。我有两个文件 - 一个FIFO,允许我将命令传递给程序,以及一个输出日志文件。
Bash脚本包含以下代码:
#!/bin/bash
java -jar file.jar <./run/command-fifo >>./run/server.log 2>&1 &
echo $! >| ./run/server.pid
老实说,我不记得为什么我在第三行使用>|
(我只知道它有效)。在java行中,第一个<
将fifo文件重定向到标准输入。 >>
应将标准输出重定向到文件,2>&1
也应将标准错误重定向到该文件。然后它在后台运行。
问题是什么都没有写入server.log文件。读取命令-fifo文件,但不写入日志。程序正在写入标准输出(如果我自己运行它可以正常工作)。
我也按this question中的建议尝试script
,但它也不起作用:
script -q /dev/null java -Xmx4G -Xms4G -jar current.jar --nogui <./run/command-fifo >>./run/server.log 2>&1 &
任何人都有想法让它正确写入日志吗?
关注:我应该更多地解释软件如何使这个解释有意义。这里有三个部分:
launchd
用于通过调用启动器脚本启动程序启动程序的plist 上面给出的脚本是启动脚本。这将启动java进程,将其pid回显到文件,然后返回。启动器脚本(此处未给出)然后在终止之前等待pid退出。如果它终止,则launchd会自动重新启动启动器脚本。
Launchd具有一项功能,可以为其启动的文件设置标准输出路径。实质上,它将启动器脚本的stdout重定向到给定文件。
我这样做了,瞧,它有效。通过将开始脚本行更改为以下内容:
java -jar file.jar <>./run/command-fifo &
它允许通过launchd捕获标准输出并将其写入文件。这是一个有点不同的解决方案,但它实际上确实有效。这很奇怪,因为启动脚本在技术上没有任何输出,因为java进程在后台,但无论它是否有效,我确实以某种方式工作。
当然,我更喜欢将文件的标准输出明确地重定向到一个文件中(在其他脚本中,可能存在多个文件的情况,我需要将它们分开)。我还在尝试并试图找到解决方案。
答案 0 :(得分:1)
我认为@ torek关于缓冲的评论可能是正确的。您可以使用stdbuf
utility:
java
进程对其输出进行行缓冲
#!/bin/bash
stdbuf -oL java -jar file.jar <./run/command-fifo >>./run/server.log 2>&1 &
echo $! >| ./run/server.pid
关于>|
运算符,@ torek也是正确的。 Here is the bash manual entry