Come usare Pipe Symbol tramite exec in Java

Sto usando il seguente codice per ottenere i dettagli di tutti i processi in esecuzione nel sistema:

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 down con il simbolo pipe, quindi uso questo:

 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. Quindi ho usato il backslash davanti al simbolo del tubo come mostrato di seguito:

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

Ma di nuovo va a ErrorStream. Come posso eseguire ps aux | grep java ps aux | grep java attraverso exec in Java?

La pipe è una caratteristica di shell: non stai usando una shell, stai eseguendo un processo ( ps ).

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

msgstr “esegui ps, quindi conduci il suo output su un altro programma (grep) e fai estrarre ciò di cui ho bisogno”

Hai solo bisogno di estrarre ciò che vuoi dall’output di ps . Usa un Matcher e presta solo attenzione alle linee che includono java da InputStream

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

Bene, se si desidera utilizzare pipe nel processo che si esegue, è necessario avviare una shell come bash e dare ps e grep sulla riga di comando a tale shell:

 bash -c "echo $PATH" 

Prova questo per capire cosa intendo, quindi usa questo:

 bash -c "ps axu | grep PATTERN" 

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

Non l’ho provato ma presumo questo:

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

Spero che questo aiuti; D

  1. È necessario separare il comando dai suoi argomenti quando si chiama exec, ad esempio .exec(new String[] { "ps", "aux" }) ( non exec("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 stream di output del primo comando al stream di input del secondo comando. Ho usato IOUtils comuni di Apache per farlo con facilità.

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

Con questi cambiamenti in atto, questo codice fa quello che vuoi:

 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); } 

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

 jps -l