Вопрос

I have a Java program that I'm running using a Bash script on Mac OS X. I have two files - a FIFO that allows me to pipe commands into the program, and an output log file.

The Bash script consists of the following code:

#!/bin/bash
java -jar file.jar <./run/command-fifo >>./run/server.log 2>&1 &
echo $! >| ./run/server.pid

I honestly can't remember why I used >| in the third line (I just know that it works). In the java line, the first < redirects the fifo file to standard input. The >> should redirect standard output to the file, and the 2>&1 should redirect standard error to it as well. It then runs in the background.

The problem is that nothing is ever written to the server.log file. The command-fifo file is read, but the log is not written. The program IS writing to standard output (if I run it on its own it works fine).

I also tried script as suggested in this question but it didn't work either:

script -q /dev/null java -Xmx4G -Xms4G -jar current.jar --nogui <./run/command-fifo >>./run/server.log 2>&1 &

Anyone have ideas to get this to write to the log properly?

FOLLOWUP: I should explain a bit more of how the software works for this explanation to make sense. There are three parts at work here:

  1. A plist that launchd uses to start the program at boot by calling the launcher script
  2. A launcher script that handles kill signals and waits for the pid of the java process
  3. A start script, called by the launcher script, that launches the program and saves its pid

The script given above is the start script. This launches the java process, echoes its pid to a file, then returns. The launcher script (not given here) then waits for the pid to exit before terminating. If it terminates, launchd automatically relaunches the launcher script.

Launchd has a feature that can set the standard output path for the file it launches. Essentially, it redirects stdout of the launcher script to the given file.

I did this, and lo and behold, it works. By changing the start script line to the following:

java -jar file.jar <>./run/command-fifo &

it allows standard output to be captured by launchd and written to the file. It's a bit different solution, but it does in fact work. It's strange because the launcher script technically has nothing to output since the java process is in the background, but however it works, it does i fact work somehow.

Of course, I'd prefer to explicitly redirect the file's standard output into a file (in other scripts there may be cases where there are more than one and I need to keep them separate). I'm still going to experiment and try to find a solution.

Это было полезно?

Решение

I think @torek's comment about buffering is probably right on the money. You can force your java process to line-buffer its output using the stdbuf utility:

#!/bin/bash
stdbuf -oL java -jar file.jar <./run/command-fifo >>./run/server.log 2>&1 &
echo $! >| ./run/server.pid

Regarding the >| operator, @torek is also correct. Here is the bash manual entry.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top