如何通过 Java 的 Runtime.getRuntime().exec 方法调用此命令?
How do I call this command via Java's Runtime.getRuntime().exec method?
以下命令 运行 在我的 Linux 终端中正确执行:
java -Djava.library.path=/home/john/native_so_libraries/linux-64 -cp '/home/john/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/john/Desktop/Dropbox/Libjitsi_linux_64/*' Main "send"
此命令为本机 .so 库指定一个文件夹(通过 Djava.library.path=/...),一个名为 "SendReceive.jar" 的应用程序 JAR 文件,一个用于 JAR 库的文件夹(通过 -cp class 路径选项),还有一个主要的 class,其中包含 运行 的主要方法,一个名为 "Main" 的 class。它有一个用引号括起来的命令行参数,即 "send" 参数。此命令有效,并且 运行 是来自终端的 Java 进程,但我不知道如何让它与来自另一个进程的 Runtime.getRuntime().exec 一起工作。
请注意,我正在尽最大努力遵循本教程中提供的说明:http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html?page=2 - 这意味着我正在使用线程来使用进程中的标准输入和标准错误流。尽管如此,当我将该终端命令变成如下字符串时,该过程不会启动:
Process process = Runtime.getRuntime().exec("java -Djava.library.path=/home/john/native_so_libraries/linux-64 -cp '/home/john/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/john/Desktop/Dropbox/Libjitsi_linux_64/*' Main \"send\"");
如何通过 Runtime.getRuntime().exec 执行此命令 运行?
简短的回答是不要。请改用 ProcessBuilder
。它允许您将每个命令行参数分隔到它自己的 String
中,这将作为单独的 "argument" 出现在进程中。这使得它对于处理其中包含空格的路径非常有用,例如...
ProcessBuilder pb = new ProcessBuilder(
"java",
"-Djava.library.path=/home/johnmichaelreed/Desktop/Dropbox/Libjitsi_linux_64/lib/native/linux-64",
"-cp",
"/home/johnmichaelreed/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/johnmichaelreed/Desktop/Dropbox/Libjitsi_linux_64",
"Main",
"\"send\"");
pb.redirectErrorStream(true);
try {
Process p = pb.start();
try (InputStream is = p.getInputStream()) {
int in = -1;
while ((in = is.read()) != -1) {
System.out.print((char)in);
}
}
int exitCode = p.exitValue();
System.out.println("Process exited with " + exitCode);
} catch (IOException ex) {
ex.printStackTrace();
}
它还允许您将 stderr 重定向到 stdout,这样更容易阅读。
您还应该阅读标准输出并检查退出值以获得更好的 digansotics
您需要做的第一件事是执行 glob (represented by *
in your classpath). You can also use a ProcessBuilder
- 用于创建操作系统进程。 并且 List<String>
或命令,以及 StringBuilder
来执行 glob。像,
public static void main(String[] args) {
String home = System.getProperty("user.home");
System.out.println(home);
List<String> command = new ArrayList<>();
command.add("java");
command.add("-Djava.library.path=" + home
+ "/native_so_libraries/linux-64");
StringBuilder cp = new StringBuilder();
cp.append(home + "/NetBeansProjects/SendReceive/dist/SendReceive.jar");
try {
File dir = new File(home + "/Desktop/Dropbox/"
+ "Libjitsi_linux_64/");
for (File f : dir.listFiles()) {
if (f.isFile()) {
cp.append(":").append(f.getCanonicalPath());
}
}
} catch (IOException e) {
e.printStackTrace();
}
command.add("-cp");
command.add(cp); // <-- shouldn't need literal
// single quotes.
command.add("Main");
command.add("send"); // <-- shouldn't need literal double quotes.
ProcessBuilder pb = new ProcessBuilder(command);
pb.inheritIO();
try {
Process p = pb.start();
System.exit(p.waitFor());
} catch (Exception e) {
e.printStackTrace();
}
}
以下命令 运行 在我的 Linux 终端中正确执行:
java -Djava.library.path=/home/john/native_so_libraries/linux-64 -cp '/home/john/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/john/Desktop/Dropbox/Libjitsi_linux_64/*' Main "send"
此命令为本机 .so 库指定一个文件夹(通过 Djava.library.path=/...),一个名为 "SendReceive.jar" 的应用程序 JAR 文件,一个用于 JAR 库的文件夹(通过 -cp class 路径选项),还有一个主要的 class,其中包含 运行 的主要方法,一个名为 "Main" 的 class。它有一个用引号括起来的命令行参数,即 "send" 参数。此命令有效,并且 运行 是来自终端的 Java 进程,但我不知道如何让它与来自另一个进程的 Runtime.getRuntime().exec 一起工作。
请注意,我正在尽最大努力遵循本教程中提供的说明:http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html?page=2 - 这意味着我正在使用线程来使用进程中的标准输入和标准错误流。尽管如此,当我将该终端命令变成如下字符串时,该过程不会启动:
Process process = Runtime.getRuntime().exec("java -Djava.library.path=/home/john/native_so_libraries/linux-64 -cp '/home/john/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/john/Desktop/Dropbox/Libjitsi_linux_64/*' Main \"send\"");
如何通过 Runtime.getRuntime().exec 执行此命令 运行?
简短的回答是不要。请改用 ProcessBuilder
。它允许您将每个命令行参数分隔到它自己的 String
中,这将作为单独的 "argument" 出现在进程中。这使得它对于处理其中包含空格的路径非常有用,例如...
ProcessBuilder pb = new ProcessBuilder(
"java",
"-Djava.library.path=/home/johnmichaelreed/Desktop/Dropbox/Libjitsi_linux_64/lib/native/linux-64",
"-cp",
"/home/johnmichaelreed/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/johnmichaelreed/Desktop/Dropbox/Libjitsi_linux_64",
"Main",
"\"send\"");
pb.redirectErrorStream(true);
try {
Process p = pb.start();
try (InputStream is = p.getInputStream()) {
int in = -1;
while ((in = is.read()) != -1) {
System.out.print((char)in);
}
}
int exitCode = p.exitValue();
System.out.println("Process exited with " + exitCode);
} catch (IOException ex) {
ex.printStackTrace();
}
它还允许您将 stderr 重定向到 stdout,这样更容易阅读。
您还应该阅读标准输出并检查退出值以获得更好的 digansotics
您需要做的第一件事是执行 glob (represented by *
in your classpath). You can also use a ProcessBuilder
- 用于创建操作系统进程。 并且 List<String>
或命令,以及 StringBuilder
来执行 glob。像,
public static void main(String[] args) {
String home = System.getProperty("user.home");
System.out.println(home);
List<String> command = new ArrayList<>();
command.add("java");
command.add("-Djava.library.path=" + home
+ "/native_so_libraries/linux-64");
StringBuilder cp = new StringBuilder();
cp.append(home + "/NetBeansProjects/SendReceive/dist/SendReceive.jar");
try {
File dir = new File(home + "/Desktop/Dropbox/"
+ "Libjitsi_linux_64/");
for (File f : dir.listFiles()) {
if (f.isFile()) {
cp.append(":").append(f.getCanonicalPath());
}
}
} catch (IOException e) {
e.printStackTrace();
}
command.add("-cp");
command.add(cp); // <-- shouldn't need literal
// single quotes.
command.add("Main");
command.add("send"); // <-- shouldn't need literal double quotes.
ProcessBuilder pb = new ProcessBuilder(command);
pb.inheritIO();
try {
Process p = pb.start();
System.exit(p.waitFor());
} catch (Exception e) {
e.printStackTrace();
}
}