I am using Groovy to execute commands on my LINUX box and get back the output, but I am not able to use | pipes somehow (i think) or may be it is not waiting for the command to finish, what is wrong, or what am i missing in my code?
My Calling function
def test()
{
String result="N"
HashMap params = IntermediateResults.get("userparams")
Map env=AppContext.get(AppCtxProperties.environmentVariables)
def fClass = new GroovyClassLoader().parseClass( new File( 'plugins/infa9/Infa9CommandExecUtil.groovy' ) )
List frows=["uname -a",
"uname -a | awk '{print\$2}'",
"uname -a | cut -d ' ' -f 2"]
List resultRows = fClass.newInstance().fetchCommandOutput( params, env, frows )
return result
}
Infa9CommandExecUtil.groovy file content Update added exitVal println
package infa9
import java.io.BufferedReader;
public class Infa9CommandExecUtil {
StringBuffer result
public Infa9CommandExecUtil() {
result = new StringBuffer()
}
public List fetchCommandOutput( Map params, Map env, List rows )
{
List outputRows = new ArrayList()
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 Output *Update added exitVal value*
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 internally using sh -c
解决方案
You cannot do pipes or redirects using String.execute(). This doesn't work in Java, so it doesn't work in Groovy either...
You can use Process.pipeTo with Groovy to simplify things:
Process proca = 'uname -a'.execute()
Process procb = 'awk {print\$2}'.execute()
(proca | procb).text
A more generic version could 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 )