lunes, 29 de octubre de 2007

Ejecutar comando de Linux desde Java


Para escribir un comando de consola de linux desde java necesitamos el siguiente codigo:

try
{
String command;
command="ls";
//command="mount -h";
final Process process = Runtime.getRuntime().exec(command);
new Thread(){
public void run(){
try{
InputStream is = process.getInputStream();
byte[] buffer = new byte[1024];
for(int count = 0; (count = is.read(buffer)) >= 0;){
System.out.write(buffer, 0, count);
}
}
catch(Exception e){
e.printStackTrace();
}
}
}.start();
new Thread(){
public void run(){
try{
InputStream is = process.getErrorStream();
byte[] buffer = new byte[1024];
for(int count = 0; (count = is.read(buffer)) >= 0;){
System.err.write(buffer, 0, count);
}
}
catch(Exception e){
e.printStackTrace();
}
}
}.start();

int returnCode = process.waitFor();
System.out.println("Return code = " + returnCode);
}
catch (Exception e){
e.printStackTrace();
}

Un thread nos tira los errores y el otro lo que devuelve al ejecutar el comando.
En un string ponemos comandos con espacios. Para mayor referencia visitar:

Foro de Sun
Java Developers Almanac

22 comentarios:

Anónimo dijo...

Hola, queria felicitarte por el blog me es de mucha ayuda para java, el ejemplo esta muy bueno, yo no conseguía que se muestre lo que "sacaba" el commndo. Bueno segui asi, saludos desde Argentina!!!!

Juancho dijo...

Hola, me gusto tu articulo. Queria preguntarte como haces para editar un archivo desde Java. Me encontre con varias explicaciones pero ningun ejemplo ilustrativo.

Desde ya te agradezco mucho.

_________
Juancho

Javihm77 dijo...

Juanchonn queres ayuda de como modificar un archivo de texto??? si se como hacerlo, pero decime que tipo de archivo queres modificar....

Juancho dijo...

Hola Javi, estoy tratando de leer un archivo en linux, editarlo desde java y guardarlo. La edicion no es tanto problema porque ya entrare a googlelandia y buscare, pero lo q no encontre con facilidad es agarrar un archivo, correrlo en modo super usuario, editarlo y guardarlo.

Nos vemos loco!. Gracias por el interes.

_________
Juancho

Javihm77 dijo...

mmm eso si nunca lo he hecho, queres x ej abrir un archivo con gedit y después guardarlo. Pues sería de probar pero no te puedo mandar ningún ejemplo xq así nunca lo hice.

Juancho dijo...

Hola Javi, la idea era algo asi. Leer un archivo de texto plano, poner su contenido en alguno contenedor que traiga java, que el usuario lo edite a gusto y por ultimo guardarlo para que las modificaciones queden en el archivo.

El problema es que en linux hay archivos que pueden ser modificados solo por superusuarios, por lo que se necesita ingresar la contraseña.
Para eso se me ocurria que podria leer el contenido (que no se necesita ser SU) y al nuevo archivo guardarlo "temporalmente" en algun lado. Al momento de que el usuario lo guarde lo que el prog de java podria hacer seria ejecutar 2 comandos.
1ro) borrar el archivo viejo ejecutando "su rm archivo.xx" (no se como se interactuaria con la terminal para ingresar el pass).
2do) "su cp archivonvo.xx /lugar"

Bueno, cualquier cosa avisame que opinas, y si hay alguna forma de interactuar con lo que la consola te va devolviendo y java.

Gracias de nuevo Javier por la buena onda que le pones al blog!!. Pocos se interesan tanto en tratar de resolver los problemas de los demas..

Un abrazon!!!.

___________
Juancho

Anónimo dijo...

Hola chicos!
salio un foro en español de java!!
era horaaaaaaaaa
y contestan los threads y no se cuelgan!

jaja
FORO DE JAVA EN ESPAÑOL

Anónimo dijo...
Este comentario ha sido eliminado por el autor.
Anónimo dijo...
Este comentario ha sido eliminado por el autor.
Anónimo dijo...

Hola a todos, Bueno, esta es mi duda, probando este codigo, con diferentes comandos de linux, me doy cuenta que en algunos necesito 2 lineas de comando en una sola consola, por ejemplo, al entrar como otro usuario "su - user", despues la consola me pide el pasword, el problema es que no puedo hacer eso, ya que al invocar Runtime.getRuntime().exec(comand); es como si se abriera una consola nueva, y por tanto, se puerde el primer comando, ya que no se como representar el "enter", para introducir la contraseña. Espero me puedan ayudar, gracias. mi correo es criswinxp@hotmail.com

Javihm77 dijo...

Fijate que yo lo que necesitaba usar era solo una linea en la consola, nunca necesite ingresar como super usuario, varios publicaron paginas aqui, yo deje dos referencias y otro puso un foro de java por que no buscas en esos sitios?
es que no estoy muy seguro de como hacer eso....
saludos

Anónimo dijo...

Hola te fecilito por el blog, quisiera saber si tienes una referencia o existe alguna clase para poder escribir comandos directamente de la gui, te explico con detalle, hago una autentificacion a un servidor solo le paso login y servidor, despues el servidor me pide mediante la consola el password, y no encuentro forma de como colocarlo. es decir mantener la misma pantalla de command y trabajar sobre ella

Anónimo dijo...

Hola buenas:
Queria felicitarte por el blog de Java, me ha ayudado mucho en todo.Pero tengo una duda y nadie sabe como resolverla, imagina el siguiente codigo:
///////////////////////////////
Runtime ejecutor = Runtime.getRuntime();
final Process process = ejecutor.exec("ls -la");
////////////////////////////////
Estoy en la plataforma de Mac, y esto mas el añadido tuyo de los dos hilos me saca el interior de la carpeta donde estoy ejecutando, funciona bien.

Pero si en vez de eso le pongo una ruta de una carpeta con espacios no funciona y he probado de todo, \\, " " de todo.Puede alguien decirme porque sucede esto?
Runtime ejecutor = Runtime.getRuntime();
final Process process = ejecutor.exec("ls -la /Users/miCarpeta/carpeta\\ copia");

Por que? el espacio hace que no encuentre la ruta correcta?

Javihm77 dijo...

Pues en Mac no se xq no he programado Java ahí pero en linux se arregla con una diagonal invertida y el espacio: /media/win/Documents\ and\ Settings$
Proba con eso... tal vez funciona

Anónimo dijo...

psht

Anónimo dijo...

psht psht

Anónimo dijo...

psht psht psht

Anónimo dijo...

psht psht psht psht

Anónimo dijo...

psht psht psht psht psht

Anónimo dijo...

Ahora que estoy aprendiendo Java...voy a pasar mi script para hacer copias de seguridad a este lenguaje a ver que tal queda..
gracias saludos..

Att: Jtux

Anónimo dijo...

ante todo felicitar por el blog, posee informacion interesante

punto de mi comentario , estoy desarrollando una aplicacion web java-servlets-dojo, lo que me sucede algo curioso ejecuto un comando linux desde mi controlador para recojer datos de esta accion pero el servidor web , se para , y la aplicacion no correo , todo me sucede despues de ejecutar el comando , si tiene alguna idea les agradecere

no puedo registrarme por errores de url , mi correo es cfernanez@estudiantes.uci.cu

Unknown dijo...

Esta es mi propuesta para ejecutar comando de UNIX desde JAVA

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Ejecutor{

//No defino constructor puesto que es una CLASE como HERRAMIENTA
//tambien sugiero hacer que todo sea static

//Esta funcion devuelve un proceso que es la ejecucion del comando
//que se le pasa como argumento con el nombre c
public Process comando(String c) throws IOException{
return Runtime.getRuntime().exec(c);
}


//Un lector de la salida que provoca el comando
public BufferedReader salidaComando(Process p){
return new BufferedReader(new InputStreamReader(p.getInputStream()));
}

//Un lector de los errores que pudieron cometerse al ejecutar el comando
public BufferedReader errorComando(Process p){
return new BufferedReader(new InputStreamReader(p.getErrorStream()));
}

//Tranforma los Buffers en texto legible
public String leerBufer(BufferedReader b) throws IOException{
String aux = "", aux2 = "";
while( (aux2 = b.readLine()) != null ){
aux+=String.format(" %s \n",aux2);
}
if(aux == "") return "SIN ERRORES!";
return aux;
}

//Nuestro famoso main para ejecutarlo
public static void main(String[] arg){
Ejecutor ejecutor = new Ejecutor();

try{
//En la siguiente linea le paso el siguiente comando
// ls /etc/init.d que mostrara todos los demonios que estan corriendo
// en el sistema.
//ahora falta que ustedes pongan lo que requieran
Process p = ejecutor.comando("ls /etc/init.d");
System.out.println("Salida comando:");
System.out.println(ejecutor.leerBufer(ejecutor.salidaComando(p)));
System.out.println("Errores comando:");
System.out.println(ejecutor.leerBufer(ejecutor.errorComando(p)));
} catch(IOException e){
System.out.println("No se ejecuto correctamente por las sgtes razones: ");
e.printStackTrace();
System.exit(0);
}

}
}


Espero les ayude en algo :)

 
;