Cómo ejecutar comandos cmd a través de Java


Estoy tratando de ejecutar argumentos de línea de comandos a través de Java. Por ejemplo:

// Execute command
String command = "cmd /c start cmd.exe";
Process child = Runtime.getRuntime().exec(command);

// Get output stream to write from it
OutputStream out = child.getOutputStream();

out.write("cd C:/ /r/n".getBytes());
out.flush();
out.write("dir /r/n".getBytes());
out.close();

Lo anterior abre la línea de comandos pero no ejecuta cd o dir. Alguna idea? Estoy ejecutando Windows XP, JRE6.

(He revisado mi pregunta para que sea más específica. Las siguientes respuestas fueron útiles, pero no responden a mi pregunta.)

 38
Author: Madhawa Priyashantha, 2010-11-11

9 answers

El código que publicaste inicia tres procesos diferentes cada uno con su propio comando. Para abrir un símbolo del sistema y luego ejecutar un comando intente lo siguiente (nunca lo probé yo mismo):

try {
    // Execute command
    String command = "cmd /c start cmd.exe";
    Process child = Runtime.getRuntime().exec(command);

    // Get output stream to write from it
    OutputStream out = child.getOutputStream();

    out.write("cd C:/ /r/n".getBytes());
    out.flush();
    out.write("dir /r/n".getBytes());
    out.close();
} catch (IOException e) {
}
 3
Author: Peter Knego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-24 12:36:29

Encontré esto en forums.oracle.com

Permite la reutilización de un proceso para ejecutar múltiples comandos en Windows: http://kr.forums.oracle.com/forums/thread.jspa?messageID=9250051

Necesitas algo como

   String[] command =
    {
        "cmd",
    };
    Process p = Runtime.getRuntime().exec(command);
    new Thread(new SyncPipe(p.getErrorStream(), System.err)).start();
    new Thread(new SyncPipe(p.getInputStream(), System.out)).start();
    PrintWriter stdin = new PrintWriter(p.getOutputStream());
    stdin.println("dir c:\\ /A /Q");
    // write any other commands you want here
    stdin.close();
    int returnCode = p.waitFor();
    System.out.println("Return code = " + returnCode);

Clase SyncPipe:

class SyncPipe implements Runnable
{
public SyncPipe(InputStream istrm, OutputStream ostrm) {
      istrm_ = istrm;
      ostrm_ = ostrm;
  }
  public void run() {
      try
      {
          final byte[] buffer = new byte[1024];
          for (int length = 0; (length = istrm_.read(buffer)) != -1; )
          {
              ostrm_.write(buffer, 0, length);
          }
      }
      catch (Exception e)
      {
          e.printStackTrace();
      }
  }
  private final OutputStream ostrm_;
  private final InputStream istrm_;
}
 62
Author: Pepe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-26 18:39:49

Si desea ejecutar varios comandos en el shell de cmd, puede construir un solo comando como este:

  rt.exec("cmd /c start cmd.exe /K \"cd c:/ && dir\"");

Esta página explica más.

 15
Author: Vincent Ramdhanie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-11 17:35:36

Cada ejecución de exec genera un nuevo proceso con su propio entorno. Así que tu segunda invocación no está conectada a la primera de ninguna manera. Simplemente cambiará su propio directorio de trabajo y luego saldrá (es decir, es efectivamente un no-op).

Si desea redactar solicitudes, deberá hacerlo dentro de una sola llamada a exec. Bash permite especificar múltiples comandos en una sola línea si están separados por punto y coma; Windows CMD puede permitir lo mismo, y si no siempre hay secuencias de comandos por lotes.

Como dice Piotr , si este ejemplo es en realidad lo que estás tratando de lograr, puedes realizar lo mismo de manera mucho más eficiente, efectiva y segura con la plataforma con lo siguiente:

String[] filenames = new java.io.File("C:/").list();
 3
Author: Andrzej Doyle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:16

Prueba este enlace

Usted no usa "cd" para cambiar el directorio desde el cual ejecutar sus comandos. Necesita la ruta completa del ejecutable que desea ejecutar.

Además, listar el contenido de un directorio es más fácil de hacer con las clases File/Directory

 2
Author: Piotr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-11 17:31:47

Cada una de sus llamadas exec crea un proceso. Las llamadas segunda y tercera no se ejecutan en el mismo proceso de shell que creó en la primera. Intente poner todos los comandos en un script bat y ejecutarlo en una llamada: rt.exec("cmd myfile.bat"); o similar

 1
Author: Carles Barrobés,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-11 17:33:18

Esto porque cada runtime.exec(..) devuelve una clase Process que debe usarse después de la ejecución en lugar de invocar otros comandos por la clase Runtime

Si miras Process doc verás que puedes usar

  • getInputStream()
  • getOutputStream()

En el que debe trabajar enviando los comandos sucesivos y recuperando la salida..

 0
Author: Jack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-11 17:35:51

Escribir en el flujo de salida desde el proceso es la dirección equivocada. 'fuera' en ese caso significa del proceso a usted. Intente obtener / escribir en el flujo de entrada para el proceso y leer desde el flujo de salida para ver los resultados.

 0
Author: Kelly S. French,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-11 18:50:02

Como también me enfrenté al mismo problema y porque algunas personas aquí comentaron que la solución no estaba funcionando para ellos, aquí está el enlace a la publicación donde se ha encontrado una solución que funciona.

Https://stackoverflow.com/a/24406721/3751590

También ver la "Actualización" en la mejor respuesta para el uso de Cygwin terminal

 0
Author: singe3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:16