从Java调用挂起shell脚本(Calling a shell script from java

2019-09-29 17:12发布

所以我想从Java文件执行产生大量输出(以MB为单位的100S)一个shell脚本。 这挂过程并无法完成。

然而,在shell脚本中,如果我的脚本输出重定向到一些日志文件或/ dev / null的的Java文件执行,并在一个瞬间完成。

难道是因为该Java程序无法完成的数据量? 如果是这样,是否有任何文件这样? 或者是有关于数据量的任何限制(记录)?

这里是你如何可以模拟这个场景。

Java的文件将是这样的:

import java.io.InputStream;

public class LotOfOutput {

    public static void main(String[] args) {
        String cmd = "sh a-script-which-outputs-huuggee-data.sh"; 
        try {
            ProcessBuilder pb = new ProcessBuilder("bash", "-c", cmd);
            pb.redirectErrorStream(true);
            Process shell = pb.start();
            InputStream shellIn = shell.getInputStream();
            int shellExitStatus = shell.waitFor();
            System.out.println(shellExitStatus);
            shellIn.close();
        } catch (Exception ignoreMe) {
        }
    }
}

该脚本a-script-which-outputs-huuggee-data.sh“可能是这样的:

#!/bin/sh
# Toggle the line below
exec 3>&1 > /dev/null 2>&1

count=1
while [ $count -le 1000 ]
do
        cat some-big-file
        ((count++))
done

echo
echo Yes I m done

免费啤酒正确的答案。 :)

Answer 1:

这是因为你不从阅读Process的产出。

按照在类的Javadoc中 ,如果你不这样做,那么你可能最终得到一个僵局; 过程填充其IO缓冲器,并等待“壳”(或收听过程)从中读取并清空它。 同时你的过程中,应这样做,阻止等待进程退出。

你要调用的getInputStream() ,并从可靠地读取(可能是从另一个线程)停止进程阻塞。

也看看五个java程序陷阱和当的Runtime.exec()将不会 -无论是关于共同面临的问题翔实的文章Process



Answer 2:

你永远读输入流,所以它可能阻止,因为输入缓冲区已满。



Answer 3:

输入/输出缓冲器具有有限的尺寸(取决于操作系统上)。 如果我没有记错,这不是大或Windows XP至少。 尝试创建一个线程,以最快的速度读取的InputStream越好。

这些方针的东西:

class StdInWorker
            implements Worker
    {
        private BufferedReader br;
        private boolean run = true;
        private int linesRead = 0;

        private StdInWorker (Process prcs)
        {
            this.br = new BufferedReader(
                    new InputStreamReader(prcs.getInputStream()));
        }

        public synchronized void run ()
        {
            String in;
            try {
                while (this.run) {
                    while ((in = this.br.readLine()) != null) {
                        this.buffer.add(in);
                        linesRead++;
                    }

                    Thread.sleep(50);
                }
            }
            catch (IOException ioe) {
                ioe.printStackTrace();
            }
            catch (InterruptedException ie) {}
        }
    }
}


文章来源: Calling a shell script from java hangs
标签: java shell