2011-08-11 85 views
0

我正在运行以下代码,并停止在waitfor()函数。可能是什么原因,我该如何解决?在Java中运行Unix命令

String line; 
Process albumProcess; 
try { 
    albumProcess = Runtime.getRuntime().exec(
    "iconv -f UTF-16 -t UTF-8 /home/gozenem/"+ xmlFileName + 
    ".xml | grep albumID"); 
    albumProcess.waitFor(); 
    BufferedReader in = new BufferedReader(
     new InputStreamReader(albumProcess.getInputStream())); 
    ArrayList<String> lineList = new ArrayList<String>(); 
    while ((line = in.readLine()) != null) { 
    lineList.add(line); 
    } 
    result[0] = lineList.size(); 
    albumProcess.destroy(); 

} catch (Exception e) {} 

回答

2

| grep ...如您所愿,因为getRuntime().exec不明白管道符号不消耗来自命令的输出。该进程陷入了等待某些东西消耗其输出它通过伪造命令行参数"|","grep""albumId"

一个shell会明白|execv不会,所以你需要使用bash -c,而不是得到一个壳里做管道(见java shell for executing/coordinating processes?做管道自己(见Pipe between java processes on command shell not reliable working)。Java 7中有一个新的ProcessBuilder类,使它很容易设置管道,所以你可以使用这些,如果你只是运行在一个流血的边缘JVM。

一旦你有grep运行,如果有一堆线匹配,它可能仍然填满了缓冲区,所以你需要一些东西坐在缓冲区上消耗进程的输出流。移动

albumProcess.waitFor(); 

while循环应该做到这一点。

+0

我如何使用bash -e?我对此很新,如果你能帮助我,那将会很棒。谢谢。 – prgrmmr

+0

@prgrmmr,'bash -c“foo”'启动一个运行命令'“foo”'的新shell然后退出。 'bash -c“foo | bar”'包括管道。所以,只需引用你的命令,并把'bash -c'放在前面。从manpage:''-c string'如果存在'-c'选项,则从字符串中读取命令。如果字符串后面有参数,则将它们分配给位置参数,从$ 0开始。 –

+0

过程通常不会等待他们的输出被消耗,是吗?它不会只写入标准输出流并退出吗?该过程必须由于其他原因而挂起。 – chesles