2011-08-29 8 views
8

Sto usando il seguente codice per ottenere i dettagli di tutti i processi in esecuzione nel sistema:Come usare Symbol tubo attraverso exec in Java

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

voglio filtrare ps aux verso il basso con il simbolo di tubo in modo che uso this:

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

Va a ErrorStream. Più tardi ho notato che il simbolo Pipe (|) è utilizzato come operatore di bitwise incluso in Java. Così ho usato backslash davanti a simbolo pipe come illustrato di seguito:

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

Ma ancora una volta si va al ErrorStream. Come posso eseguire ps aux | grep java tramite exec in Java?

+0

solo per chiarire, l'operatore OR '|' non viene interpretato all'interno delle stringhe in modo da non dovrebbe bisogno di fuggire. –

risposta

5

Il tubo è una funzione di svuotamento - non si sta usando una shell, si sta exec'ing un processo (ps).

Ma davvero, perché vorresti farlo? Quello che stai dicendo è:

"eseguire ps, poi pipe il suo output in un altro programma (grep) e lo hanno estrarre quello che mi serve"

Hai solo bisogno di estrarre ciò che si desidera dal uscita di ps . Utilizzare un Matcher e solo prestare attenzione alle linee che includono java dal InputStream

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

+0

Grazie per la risposta. Quando uso Runtime.getRuntime(). Exec ("ps aux") ci vuole tempo per elaborare tutte le linee da InputStream. Quindi pensavo che Runtime.getRuntime(). Exec ("ps aux | grep java") sarebbe semplicemente il mio lavoro. Se vado di nuovo con Matcher ci vorrà del tempo per elaborare le linee. C'è un altro modo di usare la pipa? – Vinesh

+2

In realtà non dovrebbe volerci molto più tempo per elaborare le righe con un 'Matcher' di una shell che deve eseguire un altro processo e reindirizzare l'output di' ps' su di esso. Detto questo ... io * penso * potresti eseguire una shell come '/ bin/bash -c ps aux | grep java' –

0

Spiacente, non so come collegare correttamente i risultati da un comando a un altro, ma se tutto ciò che si desidera è il processo Java, JDK viene fornito con un programma chiamato jps che fa esattamente questo. Prova questo:

jps -l 
+0

Grazie per la risposta. Ho provato il comando, produce l'elenco che contiene PID, Nome processo. Quello che sto cercando di ottenere PID% CPU% MEM VSZ RSS TTY & COMANDO. – Vinesh

5
  1. è necessario separare il comando dai suoi argomenti al momento della chiamata exec, ad esempio .exec(new String[] { "ps", "aux" }) (nonexec("ps aux")). Quando è necessario passare argomenti, è necessario richiamare la versione String [] - il primo elemento di String[] è il comando, il resto sono gli argomenti.

  2. È necessario inviare il contenuto del flusso di output del primo comando al flusso di input del secondo comando. Ho usato Apache commons IOUtils per farlo con facilità.

  3. È necessario chiudere il flusso di input della chiamata grep, altrimenti si bloccherà in attesa della fine dell'input.

Con questi cambiamenti in atto, questo codice fa ciò che si vuole:

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

E 'un rischio deadlock quando il thread è single-threaded? Potrebbe usare 'PumpStreamHandler' da commons-exec. – msandiford

+0

Commento equo. Stavo cercando di mantenere questo il più semplice possibile per illustrare i bit importanti. Attenzione: potrebbe verificarsi un deadlock in ambienti a thread singolo. – Bohemian

16

Beh, se si desidera utilizzare i tubi del processo che si exec, allora avete bisogno di avviare una shell come bash , e dare ps e grep sulla riga di comando per quel guscio:

bash -c "echo $PATH" 

Provate a capire cosa intendo, quindi utilizzare questo:

bash -c "ps axu | grep PATTERN" 

per capire come è necessario impostare java.runtime.Process.

non ho provato, ma presumo questo:

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

Speranza che aiuta; D

+0

Ehi, va benissimo! Grazie! – Erhannis

+0

Non funzionava per me ... Dopo aver letto [questo] (http://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep), alla fine decido di usare invece pgrep di grep – boly38