ejecutar - Ejecuta comandos cmd a través de java
ejecutar comandos cmd desde java (10)
Encontré varios fragmentos de código para ejecutar comandos cmd a través de la clase Java, pero no pude conseguirlo. Este código para abrir el cmd
public void excCommand(String new_dir){
Runtime rt = Runtime.getRuntime();
try {
rt.exec(new String[]{"cmd.exe","/c","start"});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Y encontré otros enlaces para agregar otros comandos como cd http://www.coderanch.com/t/109753/Linux-UNIX/exec-command-cd-command-java
¿Cómo abrir el símbolo del sistema e insertar comandos usando Java?
¿Alguien puede ayudarme a entender eso ... cómo puedo cd un directorio como:
cd C:/Program Files/Flowella
luego ejecuta otros comandos en ese directorio.
Aquí hay una implementación más completa de la ejecución de línea de comando.
Uso
executeCommand("ls");
Salida:
12/27/2017 11:18:11:732: ls
12/27/2017 11:18:11:820: build.gradle
12/27/2017 11:18:11:820: gradle
12/27/2017 11:18:11:820: gradlew
12/27/2017 11:18:11:820: gradlew.bat
12/27/2017 11:18:11:820: out
12/27/2017 11:18:11:820: settings.gradle
12/27/2017 11:18:11:820: src
Código
private void executeCommand(String command) {
try {
log(command);
Process process = Runtime.getRuntime().exec(command);
logOutput(process.getInputStream(), "");
logOutput(process.getErrorStream(), "Error: ");
process.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private void logOutput(InputStream inputStream, String prefix) {
new Thread(() -> {
Scanner scanner = new Scanner(inputStream, "UTF-8");
while (scanner.hasNextLine()) {
synchronized (this) {
log(prefix + scanner.nextLine());
}
}
scanner.close();
}).start();
}
private static SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss:SSS");
private synchronized void log(String message) {
System.out.println(format.format(new Date()) + ": " + message);
}
La forma más fácil sería usar Runtime.getRuntime.exec()
.
Por ejemplo, para obtener un valor de registro para el navegador predeterminado en Windows:
String command = "REG QUERY HKEY_CLASSES_ROOT//http//shell//open//command";
try
{
Process process = Runtime.getRuntime().exec(command);
} catch (IOException e)
{
e.printStackTrace();
}
Luego use un Scanner
para obtener la salida del comando, si es necesario.
Scanner kb = new Scanner(process.getInputStream());
Nota : el /
es un carácter de escape en una String
, y debe ser escapado para que funcione correctamente (de ahí el //
).
Sin embargo, no hay ningún ejecutable llamado cd
, porque no se puede implementar en un proceso separado.
El único caso en el que importa el directorio de trabajo actual es ejecutar un proceso externo (usando ProcessBuilder
o Runtime.exec()
). En esos casos, puede especificar explícitamente el directorio de trabajo que se usará para el proceso recién iniciado.
La manera más fácil para tu comando:
System.setProperty("user.dir", "C://Program Files//Flowella");
Mi ejemplo (del proyecto real)
archivo de carpetas.
zipFile, filesString - String;
final String command = "/bin/tar -xvf " + zipFile + " " + filesString;
logger.info("Start unzipping: {} into the folder {}", command, folder.getPath());
final Runtime r = Runtime.getRuntime();
final Process p = r.exec(command, null, folder);
final int returnCode = p.waitFor();
if (logger.isWarnEnabled()) {
final BufferedReader is = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = is.readLine()) != null) {
logger.warn(line);
}
final BufferedReader is2 = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((line = is2.readLine()) != null) {
logger.warn(line);
}
}
No puede ejecutar cd
esta manera, porque cd
no es un programa real; es una parte incorporada de la línea de comandos, y lo único que hace es cambiar el entorno de la línea de comandos. No tiene sentido ejecutarlo en un subproceso, porque entonces está cambiando el entorno de ese subproceso, pero ese subproceso se cierra inmediatamente, descartando su entorno.
Para establecer el directorio de trabajo actual en su programa real de Java, debe escribir:
System.setProperty("user.dir", "C://Program Files//Flowella");
Prueba esto:
Process runtime = Runtime.getRuntime().exec("cmd /c start notepad++.exe");
Puedes probar esto: -
Process p = Runtime.getRuntime().exec(command);
Si quieres realizar acciones como cd
, utiliza:
String[] command = {command_to_be_executed, arg1, arg2};
ProcessBuilder builder = new ProcessBuilder(command);
builder = builder.directory(new File("directory_location"));
Ejemplo:
String[] command = {"ls", "-al"};
ProcessBuilder builder = new ProcessBuilder(command);
builder = builder.directory(new File("/ngs/app/abc"));
Process p = builder.start();
Es importante que divida el comando y todos los argumentos en cadenas separadas de la matriz de cadenas (de lo contrario, la API de ProcessBuilder
no los proporcionará correctamente).
Una forma de ejecutar un proceso desde un directorio diferente al directorio de trabajo de su programa Java es cambiar el directorio y luego ejecutar el proceso en la misma línea de comando. Puede hacer esto obteniendo cmd.exe
para ejecutar una línea de comando como cd some_directory && some_program
.
El siguiente ejemplo cambia a un directorio diferente y ejecuta dir
desde allí. Es cierto que podría simplemente dirigir ese directorio sin tener que cd
, pero esto es solo un ejemplo:
import java.io.*;
public class CmdTest {
public static void main(String[] args) throws Exception {
ProcessBuilder builder = new ProcessBuilder(
"cmd.exe", "/c", "cd /"C://Program Files//Microsoft SQL Server/" && dir");
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
}
Tenga en cuenta también que estoy usando ProcessBuilder
para ejecutar el comando. Entre otras cosas, esto me permite redirigir el error estándar del proceso en su salida estándar, llamando a redirectErrorStream(true)
. Hacerlo me da solo una secuencia para leer.
Esto me da la siguiente salida en mi máquina:
C:/Users/Luke/>java CmdTest
Volume in drive C is Windows7
Volume Serial Number is D8F0-C934
Directory of C:/Program Files/Microsoft SQL Server
29/07/2011 11:03 <DIR> .
29/07/2011 11:03 <DIR> ..
21/01/2011 20:37 <DIR> 100
21/01/2011 20:35 <DIR> 80
21/01/2011 20:35 <DIR> 90
21/01/2011 20:39 <DIR> MSSQL10_50.SQLEXPRESS
0 File(s) 0 bytes
6 Dir(s) 209,496,424,448 bytes free
Una vez que obtenga la referencia a Process, puede llamar a getOutpuStream para obtener la entrada estándar del prompt cmd. Luego puede enviar cualquier comando sobre la transmisión usando el método de escritura como con cualquier otra transmisión.
Tenga en cuenta que es process.getOutputStream () que está conectado al stdin en el proceso generado. De manera similar, para obtener el resultado de cualquier comando, deberá llamar a getInputStream y luego leer esto como cualquier otra corriente de entrada.