Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Linux中使用Java执行命令并获取输出_Java_Groovy - Fatal编程技术网

在Linux中使用Java执行命令并获取输出

在Linux中使用Java执行命令并获取输出,java,groovy,Java,Groovy,我正在使用Groovy在我的Linux机器上执行命令并返回输出,但不知何故(我认为)我无法使用管道,或者它可能没有等待命令完成 代码中有什么错误或遗漏了什么 我的呼叫功能: def test() { String result="N" HashMap<String,String> params = IntermediateResults.get("userparams") Map env=AppContext.get(AppCtxProperties.env

我正在使用Groovy在我的Linux机器上执行命令并返回输出,但不知何故(我认为)我无法使用
管道,或者它可能没有等待命令完成

代码中有什么错误或遗漏了什么

我的呼叫功能:

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
}
我的输出(更新:添加的exitVal值):


注意:我在内部使用的是
sh-c
管道
|
是类似shell的bash的一个特性。要使用管道,需要运行外壳,如

"/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上下文中运行命令,即在java中传递给
exec
的命令行应该类似于
/bin/sh您的_命令

不能使用
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 )

那么,你仍然没有用Groovy的方式来做这件事(我已经向你展示了好几次)?@tim:我落后于计划,我想我会先满足需求,然后重构代码。抱歉:)我也会读取错误流,或者使用ProcessBuilder将错误定向到输出。我会将输出复制到ByteArrayOutputStream,并将其转换为字符串。@Peter Lawrey:请您举个例子,这将是一个很大的帮助。谢谢,我以为你不应该从Java调用非Java程序。否则,为什么要麻烦首先用Java编写呢?谢谢,还有什么是
.inject(null)
p,c->
在这里做什么?@Ab从一个初始累加器值开始(在本例中是
null
),然后沿着集合依次应用闭包到每个元素(闭包被放入下一个元素的累加器中的结果)。因此,在本例中,我们从
null
开始,然后第一次迭代将其设置为
c.execute()
(其中c是列表中的第一个元素),然后第二个循环,
p
是由此产生的结果进程,因此它将累加器设置为
p.execute()
。希望这有意义吗?您如何捕获输出???@AbhishekSimon我不理解问题…
结果。waitForProcessOutput(System.out,System.out)
将输出流和错误流从流程链重定向到
System.out
。因此,所有内容都显示在同一个流上…谢谢,它工作得很好。我将在我的问题中发布完整的函数,作为对其他人的更新:)
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 )