使用java在LINUX中执行命令并获取输出

我正在使用Groovy在我的LINUX盒子上执行命令并取回输出,但我无法使用| 以某种方式管道(我认为)或者可能是它没有等待命令完成,出了什么问题,或者我的代码中缺少什么?

我的通话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文件内容更新添加了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 } } 

我的输出 * 更新添加了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 

更新

注意 :我在内部使用sh -c

您不能使用String.execute()进行管道或重定向。 这在Java中不起作用,所以它在Groovy中也不起作用……

您可以将Process.pipeTo与Groovy一起使用来简化操作:

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

更通用的版本可能是:

 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 ) 

管道| 是像bash一样的shell的一个特性。 要使用管道,你需要运行一个shell,比如

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

要使用ProcessBuilder进行重定向,您可以这样做

 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. } 

版画

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

管道是shell的一个特征。 因此,如果您希望支持管道,则必须在shell上下文中运行命令,即您在java中传递给exec命令行应该看起来像/bin/sh YOUR_COMMAND