Run a command in LINUX using java and select the output

I use Groovy to execute commands in my LINUX block and return output, but I cannot use | pipes somehow (I think), or maybe he is not waiting for the completion of the command, what’s wrong, or what am I missing in my code?

My Call Function

 def test() { String result="N" HashMap<String,String> params = IntermediateResults.get("userparams") Map env=AppContext.get(AppCtxProperties.environmentVariables) def fClass = new GroovyClassLoader().parseClass( new File( 'plugins/infa9/Infa9CommandExecUtil.groovy' ) ) List<String> frows=["uname -a", "uname -a | awk '{print\$2}'", "uname -a | cut -d ' ' -f 2"] List<String> resultRows = fClass.newInstance().fetchCommandOutput( params, env, frows ) return result } 

Infa9CommandExecUtil.groovy file contents Update added exitVal println

 package infa9 import java.io.BufferedReader; public class Infa9CommandExecUtil { StringBuffer result public Infa9CommandExecUtil() { result = new StringBuffer() } public List<String> fetchCommandOutput( Map<String,String> params, Map env, List<String> rows ) { List<String> outputRows = new ArrayList<String>() try { for(item in rows) { String temp=item.toString() println "CMD:$temp" Process proc = Runtime.getRuntime().exec(temp); InputStream stdin = proc.getInputStream(); InputStreamReader isr = new InputStreamReader(stdin); BufferedReader br = new BufferedReader(isr); String line = null; result = new StringBuffer() line=null int exitVal = proc.waitFor() //do I need to wait for the thread/process to finish here? while ((line = br.readLine()) != null) { result.append(line+System.getProperty("line.separator")) //to maintain the format (newlines) } String tRes=result tRes=tRes.trim() println "OUTPUT:$tRes\nEXITVAL:$exitVal" outputRows.add(tRes) } } catch (IOException io) { io.printStackTrace();} catch (InterruptedException ie) {ie.printStackTrace();} return outputRows } } 

My Exit * Update added value exitVal *

 CMD:uname -a OUTPUT:Linux estilo 2.6.18-128.el5 #1 SMP Wed Dec 17 11:41:38 EST 2008 x86_64 x86_64 x86_64 GNU/Linux EXITVAL:0 CMD:uname -a | awk '{print$2}' OUTPUT: EXITVAL:1 CMD:uname -a | cut -d ' ' -f 2 OUTPUT: EXITVAL:1 

Update

Note I am using sh -c <command>

+4
source share
3 answers

You cannot do pipes or redirects using String.execute() . This does not work in Java, so it does not work in Groovy either ...

You can use Process.pipeTo with Groovy to simplify:

 Process proca = 'uname -a'.execute() Process procb = 'awk {print\$2}'.execute() (proca | procb).text 

A more general version might be:

 String process = 'uname -a | awk {print\$2}' // Split the string into sections based on | // And pipe the results together Process result = process.tokenize( '|' ).inject( null ) { p, c -> if( p ) p | c.execute() else c.execute() } // Print out the output and error streams result.waitForProcessOutput( System.out, System.out ) 
+12
source

Pipe | is a sign of a shell like bash. To use a channel, you need to run a shell, for example

 "/bin/bash", "-c", "uname -a | awk '{print $2}'" 

To use Redirected ProcessBuilder, you can do

 public static void main(String... args) throws IOException, InterruptedException { final String cmd = "uname -a | awk '{print $1 \" \" $3}'"; System.out.println(cmd + " => " + run(cmd)); } private static String run(String cmd) throws IOException, InterruptedException { final ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", cmd); pb.redirectErrorStream(); final Process process = pb.start(); final InputStream in = process.getInputStream(); final byte[] bytes = new byte[1024]; final ByteArrayOutputStream baos = new ByteArrayOutputStream(); // you must read the output as the program runs or it can stall. for (int len; (len = in.read(bytes)) > 0;) baos.write(bytes, 0, len); process.waitFor(); return baos.toString(); // assuming the default char encoding is ok. } 

prints

 uname -a | awk '{print $1 " " $3}' => Linux 2.6.18-274.3.1.el5 
+4
source

The pipe is a feature of the shell. Therefore, if you want the channels to be supported, you need to run the command in the shell context, i.e. Your command line, which you pass to exec in java, should look like /bin/sh YOUR_COMMAND .

+1
source

Source: https://habr.com/ru/post/1380165/


All Articles