Execute Unix system command from JAVA problem

2019-04-11 23:06发布

问题:

I am facing a weird issue with executing a system command from JAVA code.
Actually i want to get the Mac OSX system information from my JAVA App.
For that im using

Runtime.getRuntime().exec("system_profiler -detailLevel full");

This is working fine.If i print the output,it is cool. But i want to write this information to a plist file for future use.For that im using the -xml argument of system_profiler.like,

 String cmd = "system_profiler -detailLevel full -xml > "+System.getProperty( "user.home" )+"/sysinfo.plist";
 Process p = Runtime.getRuntime().exec(cmd); 

Basically this should create a plist file in the current users home directory.

But this seems to be not writing anything to file.

Am i missing something here ?

回答1:

My Java is more than rusty, so please be gentle. ;-)

  1. Runtime.exec() does not automatically use the shell to execute the command you passed, so the IO redirection is not doing anything.

  2. If you just use:

    "/bin/sh -c system_profiler -detailLevel full > path/file.plist"
    

    Then the string will be tokenized into:

    { "/bin/sh", "-c", "system_profiler", "-detailLevel", "full", ">", "path/file.plist" }
    

    Which also wouldn't work, because -c only expects a single argument.

Try this instead:

String[] cmd = { "/bin/sh", "-c", "system_profiler -detailLevel full > path/file.plist" };
Process p = Runtime.getRuntime.exec(cmd);

Of course, you could also just read the output of your Process instance using Process.getInputStream() and write that into the file you want; thus skip the shell, IO redirection, etc. altogether.



回答2:

Christian.K is absolutely correct. Here is a complete example:

public class Hello {

  static public void main (String[] args) {
    try {
      String[] cmds = {
        "/bin/sh", "-c", "ls -l *.java | tee tmp.out"};
      Process p = Runtime.getRuntime().exec (cmds);
      p.waitFor ();
      System.out.println ("Done.");
    }
    catch (Exception e) {
      System.out.println ("Err: " + e.getMessage());
    }
  }
}

If you weren't using a pipe (|) or redirect (>), then you'd be OK with String cmd = "ls -l *.java", as in your original command.

If you actually wanted to see any of the output in your Java console window, then you'd ALSO need to call Process.getInputStream().

Here's a good link: Running system commands in Java applications