如何在Java中执行Shell命令?

5
我在想是否可以发送一个shell来执行客户端-服务器ipconfig。这是可能的吗?
以下是我的本地代码:
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);
        }
    }
}

感谢您的提前帮助!
1个回答

15

我不确定你是在询问Shell命令执行还是ipconfig的一般性问题。

如果是前者,那么:是的,你可以使用Runtime.getRuntime.exec()

  1. 从Java中执行Shell命令
  2. 想要从Java调用Linux Shell命令

除了提供的答案之外,这里有一个关于如何使用“host -t a”命令进行DNS查找的示例。我通常建议阅读你获取到的列表,并将它们附加到一个字符串中以记录日志。

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");
}

另一种解决方案是使用 ProcessBuilder 并从那里执行命令,这是由 herau 建议的。为此,您需要使用 Java SE 7 及以上版本。以下是一个示例,它使用修改后的工作目录和环境启动进程,并将标准输出和错误重定向到追加到日志文件中:
 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;

如果您想了解更多关于ProcessBuilder的内容,请阅读文档:Oracle Class ProcessBuilder文档


但是我必须使用这段代码为服务器创建另一个 .java 文件吗? - Funereal
好的,最佳实践是将相关代码放在它们自己的块中。例如,创建一个Util.java文件并将其放在那里,或者更具体地说,创建一个ShellUtil.java文件,并创建一个通用函数,您可以在其中调用任何shell命令。 - ambodi
2
在 JDK 5.0 之前,唯一的方法是使用 java.lang.Runtime 类的 exec() 方法。在 JDK 5.0 之后,你可以通过一个名为 ProcessBuilder 的类,在单独的进程中执行命令。 - herau
谢谢你,herau。我之前不知道ProcessBuilder,但你说得对。我已经更新了我的答案,并加入了Process Builder选项。 - ambodi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接