devtreat devtreat - 4 months ago 22
Bash Question

How to execute shell command in Java?

I was thinking if I could send a shell to execute Client-Server ipconfig. Is that possible?

This is my code in Local:

class Comando {
public static void main(String args[]) {

String s = null;

try {

// Determinar en qué SO estamos
String so = System.getProperty("os.name");
String comando;
// Comando para Linux
if (so.equals("Linux"))
comando = "ifconfig";
// Comando para Windows
else
comando = "ipconfig";

// Ejcutamos el comando
Process p = Runtime.getRuntime().exec(comando);

BufferedReader stdInput = new BufferedReader(new InputStreamReader(
p.getInputStream()));

BufferedReader stdError = new BufferedReader(new InputStreamReader(
p.getErrorStream()));

// Leemos la salida del comando
System.out.println("Ésta es la salida standard del comando:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}

// Leemos los errores si los hubiera
System.out
.println("Ésta es la salida standard de error del comando (si la hay):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}

System.exit(0);
} catch (IOException e) {
System.out.println("Excepción: ");
e.printStackTrace();
System.exit(-1);
}
}
}


Thank You in Advance!

Answer

Not a very Stackoverflow friendly question, since I am not sure if you are asking about Shell command execution, or ipconfig in general.

If the first is the case here: Yep, you can use Runtime.getRuntime.exec(). Related Answers (In Stackoverflow):

  1. Executing shell commands from Java
  2. Want to invoke a linux shell command from Java

Moreover to the answers provided there, here is my example on how you do it with "host -t a" command for DNS lookups. I would generally recommend to read through the list you get and append them in an String for logging purposes.

p = Runtime.getRuntime().exec("host -t a " + domain);
p.waitFor();

BufferedReader reader = 
  new BufferedReader(new InputStreamReader(p.getInputStream()));

String line = "";           
while ((line = reader.readLine())!= null) {
    sb.append(line + "\n");
}

The other solution which herausuggested was to use ProcessBuilderand execute the command from there. For this you need to use Java SE 7 upwards. Here is an example that starts a process with a modified working directory and environment, and redirects standard output and error to be appended to a log file:

 ProcessBuilder pb =
   new ProcessBuilder("myCommand", "myArg1", "myArg2");
 Map<String, String> env = pb.environment();
 env.put("VAR1", "myValue");
 env.remove("OTHERVAR");
 env.put("VAR2", env.get("VAR1") + "suffix");
 pb.directory(new File("myDir"));
 File log = new File("log");
 pb.redirectErrorStream(true);
 pb.redirectOutput(Redirect.appendTo(log));
 Process p = pb.start();
 assert pb.redirectInput() == Redirect.PIPE;
 assert pb.redirectOutput().file() == log;
 assert p.getInputStream().read() == -1;

If you wanna know more about ProcessBuilder, read through the documentation: Orcale Documentation on Class ProcessBuilder