0

I'm working on a Java program that calls several Shell scripts within JUnit tests (hence no output except .'s and E's) that manipulate files and SQL tables and then compares data in said tables to their expected values. Everything works in theory, however I'm encountering a strage bug where one type of test works as expected while the other type fails after a ten minute time-out. I've isolated the problem to be one of the Shell scripts, however I did not write this script and I'm unable to change it in any way. The best way I can troubleshoot this is saving the output of the script in question, which comes from a series of echo calls. Is there a somewhat straightforward/reliable way to save echo output? I've googled a bit but nothing's come up. I haven't tried to store the output yet so I don't have an attempt to show you, but the code I've already written that may be relevant is:

//Currently using BufferedWriter, File, FileWriter, IOException, and Writer
import java.io.*;

//Method to write to a log file
public void record(String input) throws IOException {
  writer = new BufferedWriter(new FileWriter(file,true));
  writer.write(input + "\n");
  writer.close();
}

Runtime rt = Runtime.getRuntime();

//Several of these since a lot of file manipulation/script running occurs
process = rt.exec("./shell.sh");
process.waitFor();

In another question I asked, someone recommended not using Runtime.exec() for several reasons. While I realize the advantages to not using exec(), I need to for this version of the program.

The tl;dr question: Can my Java program easily run shell scripts as well as save their echo'd output? If not, is there a tail -f equivalent for reading the output?

Chris
  • 1,465
  • 1
  • 18
  • 36
  • I guess this is a similar question: http://stackoverflow.com/questions/5711084/java-runtime-getruntime-getting-output-from-executing-a-command-line-program – DRCB Apr 16 '12 at 14:30
  • You could use Commons Exec. See http://stackoverflow.com/questions/6295866/how-can-i-capture-the-output-of-a-command-as-a-string-with-commons-exec for an example. – Kkkev Apr 16 '12 at 21:10

2 Answers2

1

How about use write a new script file, say scriptWithOutput.sh, to redirect the echoes to a log file

#!/bin/sh

log="someDir/someLog.log"

# This saves all you "echoes" to the log file
exec &> $log

# Your shell script
./shell.sh

And then in your Java code

process = rt.exec("./scriptWithOutput.sh");

Then try to read the someDir/someLog.log from Java?

Sicong
  • 315
  • 2
  • 6
  • I like this idea, although I have no experience writing shell scripts. Preferably I'd like to solve this issue within Java since I have the most experience writing/debugging Java, but if this is the way to go from a shell scripter's perspective then I'll start googling beginner tutorials. – Chris Apr 16 '12 at 14:42
1

To do this as painlessly as possible you should really use Asyncronous reading and writing of the output of the external process. That is what is probably blocking and causing the time outs, is the way the script is echoing it's contents back, and they are not being consumed.

I posted an answer to this exact same question a while ago, this works in all situations when reading from external processes, and is the why of why not to use Process.exec() anymore and use ProcessBuilder.

Community
  • 1
  • 1
  • After some head scratching and a little more Googling I decided on this method since it will make the most sense when I need to increase the complexity of my current functionality. Thanks for the suggestion! – Chris Apr 17 '12 at 14:03