Running an external program with Java

I am trying to execute a program from Java code. Here is my code:

public static void main(String argv[]) { try { String line; Process p = Runtime.getRuntime().exec( "/bin/bash -c ls > OutputFileNames.txt"); BufferedReader input = new BufferedReader( new InputStreamReader(p.getInputStream())); while ((line = input.readLine()) != null) { System.out.println(line); } input.close(); } catch (Exception err) { err.printStackTrace(); } } 

My OS is Mac OS X 10.6.

If I remove "> OutputFileNames.txt" from the getRuntime().exec() method, all the file names will be printed to the console just fine. But I need this to be printed in the file.

Also, if I changed the command to:

 Process p = Runtime.getRuntime().exec( "cmd \c dir > OutputFileNames.txt"); 

and run it on Windows, it launches and prints the results in a file also fine.

I read other messages to run another Java application, but none of them dealt with my problem.

I would really appreciate any help I can get.

Thanks,

+7
java terminal macos
source share
3 answers

In order for the redirect to work as it is written, you need to do the following:

 Process p = Runtime.getRuntime().exec( new String[]{"/bin/bash", "-c", "ls > OutputFileNames.txt"}); 

The problem you are facing is the easy way that Runtime.exec(String) splits the command line into arguments.

If you ran this command (as is) on the command line, you would have to enter it as:

 $ /bin/bash -c "ls > OutputFileNames.txt" 

because the -c option for bash requires the command line for the spawned shell as one shell argument. But if you put the bare quotes in the Java string, the Runtime.exec(String) method still gets the splitting. The only solution is to provide the command arguments as an array.

+8
source share

A few things to look at.

  • check in which directory your program is running (by running pwd in the same way), then check if you have write permissions to this directory.
  • see if this OutputFileNames.txt file already OutputFileNames.txt (and check permissions).
  • if the file exists, delete it and re-run it to see if it will be recreated, and see the contents, if any.
  • try using the command "/bin/bash -c 'ls > OutputFileNames.txt'" - perhaps the output of bash does not match the output of ls (in your example, redirection can be applied to bash , not ls ).
+1
source share

The problem arises because the standard process file is sent to the file, so java Process cannot collect the result.

If you want the result to be written to a file and readable in java, you have two options:

  • Keep the redirection in place and then read the list from OutputFile.txt in java, for example. using new FileReader("OutputFile.txt") . Note that exec() is asynchronous and may return before the process completes writing to the file, so you will need to wait for the process to complete using Process.waitFor() .
  • Remove the redirect and read the list directly in java (how you do it.) Then you can write this list to a file using FileWriter .

The bottom line is that you cannot use both call forwarding or read the output of a process at the same time - this is one or the other.

EDIT: Your comments indicate 1) is the preferred approach. This will write the output to a file (using the OS shell), which you then read from java when the process terminates.

+1
source share

All Articles