有没有办法在 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 作业,因为我需要知道 PID 是否存在于 Java 应用程序中。有什么想法吗?
提前致谢。
编辑:无法使用 cron 作业
编辑:我在结束后创建一个相同类型(PS)的新Thread
,所以我每次肯定都会创建一个新的ProcessBuilder。
编辑:我把不起作用的循环放回去,因为它引起了困惑。
最佳答案
我不确定循环在哪里,但每次循环都需要创建一个新的 Proc
对象(从而创建一个新的 InputStream
)。否则,您将始终查看第一次调用的结果。 ProcessBuilder
的 javadoc 表明您不需要每次都创建其中一个。
还可能存在竞争条件,即当您调用 available()
时输入流尚未准备好。在打印结果之前,您应该确保输入流已达到 EOF(这将在 ps 中发生,但不会在 top 中发生)。
尽管我不知道“ps”的输出是什么类型的编码(ASCII 之外),但您也没有正确处理编码。由于“ps”可能是 ASCII,因此相当安全,但对于其他命令(以及其他输入流)可能不安全。
关于java - 在 Java 中重复 Unix 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1040214/