44

I am attempting to be cheap and execute a local system command (uname -a) in Java. I am looking to grab the output from uname and store it in a String. What is the best way of doing this? Current code:

public class lame {

    public static void main(String args[]) {
        try {
            Process p = Runtime.getRuntime().exec("uname -a");
            p.waitFor();
            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line=reader.readLine();

            while (line != null) {    
                System.out.println(line);
                line = reader.readLine();
            }

        }
        catch(IOException e1) {}
        catch(InterruptedException e2) {}

        System.out.println("finished.");
    }
}
Brad Mace
  • 27,194
  • 17
  • 102
  • 148
Eric Schulman
  • 443
  • 1
  • 4
  • 5

5 Answers5

69

Your way isn't far off from what I'd probably do:

Runtime r = Runtime.getRuntime();
Process p = r.exec("uname -a");
p.waitFor();
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";

while ((line = b.readLine()) != null) {
  System.out.println(line);
}

b.close();

Handle whichever exceptions you care to, of course.

John Feminella
  • 303,634
  • 46
  • 339
  • 357
  • Can combine this with `org.apache.commons.io.IOUtils.toString(p.getInputStream(), "UTF-8")` from Apache Commons for small outputs (as one String) – acros Mar 16 '22 at 20:28
8

That is the best way to do it. Also you can use the ProcessBuilder which has a variable argument constructor, so you could save a line or two of code

Azder
  • 4,698
  • 7
  • 37
  • 57
  • It's not the *best* way since the command is executed using shell and, in result, it's susceptible to OS command injection if the command arguments are taken from user input. `ProcessBuilder` is definitely safer in this aspect. – kravietz Jun 03 '16 at 19:18
  • "I am attempting to be cheap and execute a local system command (uname -a)..." - it is the BEST way to be cheap and execute a local system command. What you refer to is the best way to be UNsusceptible to OS command injection ;) – Azder Jun 07 '16 at 07:57
  • 2
    You know, it's a bit like asking a programmer for the *fastest* way down the cliff... :) I have found OS command injections in a Java apps using a StackOverflow-inspired execution pattern, so I think anything that mentions Runtime.exec() deserves a big, fat warning here. – kravietz Jun 11 '16 at 07:04
  • 1
    You know, it's a lot like that, I agree, still... can't really change people's behavior if they just copy-paste from SO instead of re-evaluate their original idea, big fat warnings included :( – Azder Jun 13 '16 at 09:41
2

What you are doing looks fine. If your command is only returning a single string, you don't need the while loop, just store the reader.readLine() value in a single String variable.

Also, you probably should do something with those exceptions, rather than just swallowing them.

Andy White
  • 86,444
  • 48
  • 176
  • 211
1

I know this is very old but still...

Reading the article here: http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html
It is my understanding that you should first read the output and error streams of your executed command and only then waitFor the return value of your process.

epeleg
  • 10,347
  • 17
  • 101
  • 151
0

I know this questionis very old, but I just wanted to add some information that might come handy to some people.

If you just want to run uname command from java code, better use the System class to get information about the system.

It will not only remove the dependency of running the terminal command, but it will also work independently of the Operating System.

System Class can give you the following information

Keys : Values

--> os.version : OS Version
--> os.name : OS Name

--> os.arch : OS Architecture

--> java.compiler : Name of the compiler you are using

--> java.ext.dirs : Extension directory path

--> java.library.path : Paths to search libraries whenever loading

--> user.dir : Current working directory of User

--> user.name : Account name of User

--> java.vm.version : JVM implementation version

--> java.vm.name : JVM implementation name

--> java.home : Java installation directory

--> java.runtime.version : JVM version

(Source - https://www.geeksforgeeks.org/getproperty-and-getproperties-methods-of-system-class-in-java/)

ex : If I am running a Linux based system, Say Ubuntu, the following command will give me the information about it.

System.getProperty("os.name");
Mohd Naved
  • 448
  • 6
  • 20