2011-08-29 7 views
8

Estoy utilizando el código siguiente para obtener los detalles de todos los procesos que se ejecutan en el sistema:Cómo utilizar símbolo de canalización a través ejecutivo en Java

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

que desea filtrar ps aux abajo con el símbolo de canalización, 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. Por lo que utiliza la barra invertida delante de la barra vertical como se muestra a continuación:

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

Pero de nuevo se va a la flujoError. ¿Cómo puedo ejecutar ps aux | grep java a través de exec en Java?

+0

Solo para aclarar, el operador binario OR '|' no se interpreta dentro de cadenas por lo que no debe necesito escapar de eso –

Respuesta

5

El tubo es una operación Vaciado - no se está usando una concha, que está exec'ing un proceso (ps).

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

"ejecutar ps, a continuación, canalizar su producción a otro programa (grep) y tienen que extraer lo que necesito"

sólo tiene que extraer lo que quiere de la salida de ps . Use un Matcher y sólo prestar atención a las líneas que incluyen java de su InputStream

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

+0

Gracias por su respuesta. Cuando uso Runtime.getRuntime(). Exec ("ps aux") toma tiempo procesar todas las líneas de InputStream. Así que pensé que Runtime.getRuntime() .exe ("ps aux | grep java") simplemente sería mi trabajo. Si voy con Matcher nuevamente, tomará tiempo procesar las líneas. ¿Hay alguna otra manera de usar tubería? – Vinesh

+2

Realmente no debería tomar mucho más tiempo para que usted procese las líneas con un 'Matcher' que un intérprete de comandos que tenga que ejecutar otro proceso y obtener la salida de' ps'. Dicho eso ... creo * que podría ejecutar un shell como '/ bin/bash -c ps aux | grep java' –

0

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 programa llamado jps que hace exactamente esto. Prueba esto:

jps -l 
+0

Gracias por la respuesta. Intenté el comando, produce la lista que contiene PID, nombre del proceso. Lo que estoy buscando para obtener PID% CPU% MEM VSZ RSS TTY & COMMAND. – Vinesh

5
  1. Es necesario separar el comando de sus argumentos al llamar ejecutivo, por ejemplo .exec(new String[] { "ps", "aux" }) (noexec("ps aux")). Cuando necesite pasar argumentos, necesita invocar la versión String [] - el primer elemento de String[] es el comando, el resto son los argumentos.

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

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

Con estos cambios en su lugar, el código hace lo que quiere:

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<String> result = IOUtils.readLines(p2.getInputStream()); 
    System.out.println(result); 
} 
+2

¿Es un riesgo de interbloqueo con un solo subproceso? Podría usar 'PumpStreamHandler' de commons-exec. – msandiford

+0

Comentario justo. Estaba tratando de mantener esto lo más simple posible para ilustrar a los bits importantes. Precaución: puede bloquearse en entornos de subproceso único. – Bohemian

16

Bueno, si desea utilizar tubos en el proceso que exec, entonces usted necesita para iniciar un shell como bash y dar ps y grep en la línea de comandos para que la shell:

bash -c "echo $PATH" 

probar este para entender lo que quiero decir, a continuación, utilizar esto:

bash -c "ps axu | grep PATTERN" 

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

yo no lo probé pero supongo que esto:

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

Espero que ayude; D

+0

¡Oye, eso funciona genial! ¡Gracias! – Erhannis

+0

Eso no me funcionaba ... Después de leer [esto] (http://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep), finalmente decido usar pgrep en su lugar de grep – boly38

Cuestiones relacionadas