Java Process Builder没有执行多个命令



大家好,我是Java新手。

我目前正在构建一个Java应用程序,使用Java Process builder执行多个linux命令。

我计划执行一个shell脚本,由于这个shell脚本是一个外部程序,需要大约一秒钟才能完全执行,所以让进程休眠一秒钟,并将结果写入一个txt文件。

这是一个外部程序,它必须接收"要退出程序,所以我最后需要在终端中输入q。

我以前在这个社区得到过帮助,我用这些帮助构造的代码如下。

public static void Linux(String fileName){
try {
File dir = new File("/usr/local/bin");
ProcessBuilder pb = new ProcessBuilder(new String[]{"/bin/bash", "-c", "./test_elanprv2.2.sh > "$1"; sleep 1; q", "_", fileName + ".txt"});
System.out.println("wrote text");
pb.directory(dir);
Process start = pb.start();
start.destroy();
}catch (Exception e){
e.printStackTrace();
System.out.println("failed to write text");
}

进程构建器确实创建了一个txt文件,但它似乎是空的,并且无论我将睡眠设置为多长时间,程序似乎都会立即返回打印语句。

如果有人能告诉我我做错了什么,我将不胜感激。

提前感谢!!

正如@VGR所提到的,尝试使用redirectOutput

public static void Linux(String fileName){
try {
File dir = new File("/usr/local/bin");
ProcessBuilder pb = new ProcessBuilder(new String[]{"/bin/bash", "-c", "./test_elanprv2.2.sh");
File output = new File("_", fileName + ".txt");
pb.redirectOutput(output);
System.out.println("wrote text");
pb.directory(dir);
Process start = pb.start();
start.destroy();
} catch (Exception e) {
e.printStackTrace();
System.out.println("failed to write text");
}

您的大多数问题都是由于误解了流程的工作方式。这些概念不是Java概念;使用其他语言也会遇到同样的问题。

首先,您在进程运行之前,甚至可能在它开始之前就破坏了它。这是因为pb.start()启动了这个过程,然后你立即破坏了它,没有给它完成的机会。

你根本不需要破坏进程。让它结束吧:

Process start = pb.start();
start.waitFor();

所有过程都有自己的标准输入标准输出。再次强调,这不是Java的概念;这是Unix和Windows操作系统长期以来的基本特性。

通常,当进程通过将信息写入其标准输出来打印信息时。这实际上就是Java的System.out.println所做的。在Unix shell(和Windows)中,>字符将进程的标准输出重定向到一个文件;该程序仍然写入其标准输出,而不知道操作系统正在将该输出发送到终端以外的目的地。由于这是一个基本的操作系统功能,Java可以为您完成:

ProcessBuilder pb =
new ProcessBuilder("/bin/bash", "-c", "./test_elanprv2.2.sh");
pb.redirectOutput(new File(fileName + ".txt"));

同样,当一个进程想要获取输入时,它通常通过从标准输入中读取来实现。这与执行另一个命令不同。当你这样做时:

./test_elanprv2.2.sh > "$1"; sleep 1; q

您没有将q发送到shell脚本。上面的命令等待shell脚本完成,然后执行一个sleep,然后尝试执行一个名为q的程序(可能不存在)。

由于test_elanprv2.2.sh shell脚本可能通过读取其标准输入来接受命令,因此您希望将q命令发送到该进程的标准输入:

ProcessBuilder pb =
new ProcessBuilder("/bin/bash", "-c", "./test_elanprv2.2.sh");
pb.redirectOutput(new File(fileName + ".txt"));
Process start = pb.start();
Thread.sleep(1000);
try (Writer commands = new OutputStreamWriter(start.getOutputStream())) {
commands.write("qn");
}
// Caution: Call this AFTER writing commands.  You don't want to write
// to the standard input of a process that has already finished!
start.waitFor();

最新更新