Redirection with Runtime.getRuntime().exec() doesn't work
Asked Answered
V

2

6

I need to execute a command from a program. The command line is ok, I tried it in the terminal, but it doesn't work in the program.

I add a copy from my code:

  File dir = new File("videos"); 
  String[] children = dir.list(); 
  if (children == null) { 
   // Either dir does not exist or is not a directory 
   System.out.print("No existe el directorio\n");
   } else { 
    for (int i=0; i<children.length; i++) { 
     // Get filename of file or directory 
     String filename = children[i];

     //Recojo el momento exacto
     System.out.print("\n" +filename);

     Process p = Runtime.getRuntime().exec("exiftool -a -u -g1 -j videos/"+filename+">metadata/"+filename+".json");
    }

The program must get the name of all of the files in a folder (filename) and extract the metadata of theese videos, writting them on a .json files in the folder 'metadata'.
Where is the problem?

Vivianaviviane answered 28/6, 2010 at 7:50 Comment(1)
By the way - avoid saying "it doesn't work." This doesn't give anyone any information to go on (although in this case it worked out). Instead, you should give the output/error messages you got that made you think something was wrong. If necessary you should also clarify what you expected to happen, and what actually happened (highlighting where they were different).Hanker
H
13

The problem is, the redirection character (>) is a shell-based construct, not an executable. So unless you're running this command through something like bash (which you're not), it's going to be interpreted as a literal character argument to your exiftool invocation.

If you want to get this to work, you have two options:

  1. Get bash to do it - pass the whole command line as an argument to bash -c. This might need some heroic escaping, although in your case it looks OK.
  2. Do the redirection yourself within Java. Invoke the command without the redirected output (i.e. everything up to the > sign), then read from the process' outputstream and write all the contents to the appropriate file.

The latter approach sounds like more work initially, but when you consider that you need to always read a Process' output anyway (see the javadocs, second paragraph), it's actually very little extra on top of that. You're simply sending this output to a file instead of throwing it away.

Hanker answered 28/6, 2010 at 8:1 Comment(1)
As a general reference to Runtime.exec related problems I suggest the ancient, but still very appropriate article When Runtime.exec() won't.Brazzaville
A
3

If you have Java 7, it's easier:

Process p = new ProcessBuilder()
    .command("exiftool", "-a", "-u", "-g1", "-j",
             new File("videos", filename).toString())
    .redirectOutput(new File("metadata", filename + ".json"))
    .start();

This falls under "solution 2", but the runtime library takes care of the boilerplate.

Alpestrine answered 24/10, 2013 at 4:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.