Cómo usar Pipe Symbol a través de exec en Java

Estoy usando el siguiente código para obtener los detalles de todos los procesos que se ejecutan en el sistema:

Process p = Runtime.getRuntime().exec("ps aux"); BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); 

Quiero filtrar ps aux hacia abajo con el símbolo de la tubería, así que uso esto:

 Process p = Runtime.getRuntime().exec("ps aux | grep java"); 

Va al ErrorStream. Más tarde noté que el Símbolo de pipa (|) se utiliza como Operador OR con inclusión de bits en Java. Así que usé la barra invertida delante del símbolo de la tubería como se muestra a continuación:

 Process p = Runtime.getRuntime().exec("ps aux \\| grep java"); 

Pero de nuevo va al ErrorStream. ¿Cómo puedo ejecutar ps aux | grep java ps aux | grep java través de exec en Java?

La tubería es una característica de shell: no está utilizando un shell, está ejecutando un proceso ( ps ).

Pero realmente, ¿por qué querrías hacer esto? Lo que estás diciendo es:

“ejecuta ps, luego canaliza su salida a otro progtwig (grep) y haz que extraiga lo que necesito”

Solo necesita extraer lo que quiere de la salida de ps . Use un Matcher y solo preste atención a las líneas que incluyen java desde su InputStream

http://download.oracle.com/javase/6/docs/api/java/util/regex/Matcher.html

Bueno, si quieres usar pipes en el proceso que ejecutas, entonces necesitas iniciar un shell como bash, y dar ps y grep en la línea de comando a ese shell:

 bash -c "echo $PATH" 

Intenta esto para entender lo que quiero decir, luego usa esto:

 bash -c "ps axu | grep PATTERN" 

para entender cómo debe configurar su java.runtime.Process.

No lo probé, pero asumo esto:

 Process p = Runtime.getRuntime().exec(new String[] { "bash", "-c", "ps axu | grep PATTERN" }); 

Espero que ayude; D

  1. .exec(new String[] { "ps", "aux" }) separar el comando de sus argumentos al llamar a exec, por ejemplo, .exec(new String[] { "ps", "aux" }) ( no exec("ps aux") ). Cuando necesite pasar argumentos, necesita invocar la versión String [] – el primer elemento de String[] es el comando, el rest son los argumentos.

  2. Debe enviar el contenido de la secuencia de salida del primer comando a la secuencia de entrada del segundo comando. Utilicé Apache commons IOUtils para hacer esto con facilidad.

  3. Debe cerrar la secuencia de entrada de la llamada grep , de lo contrario se bloqueará esperando el final de la entrada.

Con estos cambios en su lugar, este código hace lo que desea:

 import org.apache.commons.io.IOUtils; public static void main(String[] args) throws Exception { Process p1 = Runtime.getRuntime().exec(new String[] { "ps", "aux" }); InputStream input = p1.getInputStream(); Process p2 = Runtime.getRuntime().exec(new String[] { "grep", "java" }); OutputStream output = p2.getOutputStream(); IOUtils.copy(input, output); output.close(); // signals grep to finish List result = IOUtils.readLines(p2.getInputStream()); System.out.println(result); } 

Lo siento, no sé cómo canalizar correctamente los resultados de un comando a otro, pero si todo lo que desea es el proceso de Java, el JDK viene con un progtwig llamado jps que hace exactamente esto. Prueba esto:

 jps -l