繁体   English   中英

在Java中重复Unix命令

[英]Repeat Unix Command in Java

有没有办法在Java中定期运行Unix命令(本例中为ps )? 我写的循环:

while( this.check )
{
    try 
    {
            ProcessBuilder pb = new ProcessBuilder("ps");
            Process proc;

            System.out.println(" * * Running `ps` * * ");

            byte[] buffer;
            String input;

            proc = pb.start();
            BufferedInputStream osInput = 
                new BufferedInputStream(proc.getInputStream());

            //prints 0 every time after the first
            System.out.println(osInput.available());

            buffer = new byte[osInput.available()];
            osInput.read(buffer);
            input = new String(buffer);
            for( String line : input.split("\n"))
            {
                if( line.equals("") )
                    continue;
                this.handlePS(line);
            }

            proc.destroy();
            try 
            {
                Thread.sleep(10000);
            } 
            catch (InterruptedException ie) 
            {
                ie.printStackTrace();
            }
        } 
        catch (IOException ioe) 
        {
            ioe.printStackTrace();
        }
    }
}

不起作用。 第一次运行非常好,但是之后每次输入流中都有0字节可用。 我尝试使用watch命令,但是此Solaris框没有该命令。 我无法使用cron作业,因为我需要知道Java应用程序中是否存在PID。 有任何想法吗?

提前致谢。

编辑:无法使用cron作业

编辑:结束后,我将制作一个相同类型(PS)的新Thread ,因此,我肯定每次都在制作一个新的ProcessBuilder。

编辑:我把循环不起作用,因为它引起混乱。

我不确定循环在哪里,但是每次循环时您都需要创建一个新的Proc对象(从而创建一个新的InputStream )。 否则,您将始终在第一个呼叫中查看结果。 ProcessBuilder指示您不需要每次都创建其中之一。

在您调用call available()时,也可能存在竞争条件,其中输入流尚未准备就绪。 在打印结果之前,您应该确保输入流已经达到EOF(这将通过ps发生,尽管不是,例如top会发生)。

尽管我不知道“ ps”的输出是哪种编码(ASCII之外),但您也无法正确处理编码。 由于“ ps”可能是ASCII,因此这是相当安全的,但可能不适用于其他命令(以及其他输入流)。

除了Kathy的回答,您还应该为每个调用在单独的线程中收集stdout和stderr。 否则,该过程将阻塞,等待您读取此数据。

有关更多详细信息,请参见此答案

编辑。 您是否在调用waitFor()来收集任何退出状态? 我通常采用的方法是执行然后调用waitFor() 我认为destroy()在这种情况下可能是多余的。

因此,我认为问题在于您正在ps执行结束之前检查输入流。 尝试添加:

proc.waitFor()

在调用osInput.available()之前。

这是我将如何实现的方法:

    TimerTask task = new TimerTask() {

        private void work() throws Exception {
            System.out.println("Now");
            ProcessBuilder pb = new ProcessBuilder("ps");
            Process p = pb.start();
            p.waitFor();
            BufferedReader reader
                = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                // Process line
                System.out.println(line);
            }
        }

        @Override
        public void run() {
            try {
                work();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    Timer timer = new Timer();
    long period = 5000;
    timer.scheduleAtFixedRate(task, 0, period);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM