Java Runtime.exec 失败 space 在 linux
Java Runtime.exec fail with space in linux
我搜索了很多但没有找到解决方案。
我的目标是 使用 java 调用命令并在 windows 和 linux 中获取输出。我找到了 Runtime.exec
方法并做了一些实验。
一切正常,除非命令参数中有 space。
测试代码如下,也在github.
该代码在 windows 上运行良好,但在 linux 上,输出为空:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) {
try {
Runtime rt = Runtime.getRuntime();
String[] commandArray;
if (isWindows()) {
commandArray = new String[]{"cmd", "/c", "dir", "\"C:\Program Files\""};
} else {
commandArray = new String[]{"ls", "\"/root/a directory with space\""};
}
String cmd = String.join(" ",commandArray);
System.out.println(cmd);
Process process = rt.exec(commandArray);
BufferedReader input = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String result = "";
String line = null;
while ((line = input.readLine()) != null) {
result += line;
}
process.waitFor();
System.out.println(result);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static boolean isWindows() {
String OS = System.getProperty("os.name").toLowerCase();
return (OS.indexOf("win") >= 0);
}
}
如果我直接执行bash中的打印命令,那么输出是符合预期的。
[root@localhost javatest]# javac Main.java
[root@localhost javatest]# java Main
ls "/root/a directory with space"
[root@localhost javatest]# ls "/root/a directory with space"
a.txt b.txt
[root@localhost javatest]#
谁能解释一下原因并给出解决方法?
exec
有两个版本。
-
在这里,您可以使用与在命令行中类似的方式指定命令,即您需要用空格引用参数。
cmd /c dir "C:\Program Files"
-
此处单独指定参数,因此参数按原样给出,即不带引号。 exec
方法将处理参数中的任何空格和引号字符,根据需要正确引用和转义参数以执行命令。
cmd
/c
dir
C:\Program Files
因此,删除您添加的额外引号:
if (isWindows()) {
commandArray = new String[] { "cmd", "/c", "dir", "C:\Program Files"};
} else {
commandArray = new String[] { "ls", "/root/a directory with space"};
}
我搜索了很多但没有找到解决方案。
我的目标是 使用 java 调用命令并在 windows 和 linux 中获取输出。我找到了 Runtime.exec
方法并做了一些实验。
一切正常,除非命令参数中有 space。
测试代码如下,也在github.
该代码在 windows 上运行良好,但在 linux 上,输出为空:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) {
try {
Runtime rt = Runtime.getRuntime();
String[] commandArray;
if (isWindows()) {
commandArray = new String[]{"cmd", "/c", "dir", "\"C:\Program Files\""};
} else {
commandArray = new String[]{"ls", "\"/root/a directory with space\""};
}
String cmd = String.join(" ",commandArray);
System.out.println(cmd);
Process process = rt.exec(commandArray);
BufferedReader input = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String result = "";
String line = null;
while ((line = input.readLine()) != null) {
result += line;
}
process.waitFor();
System.out.println(result);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static boolean isWindows() {
String OS = System.getProperty("os.name").toLowerCase();
return (OS.indexOf("win") >= 0);
}
}
如果我直接执行bash中的打印命令,那么输出是符合预期的。
[root@localhost javatest]# javac Main.java
[root@localhost javatest]# java Main
ls "/root/a directory with space"
[root@localhost javatest]# ls "/root/a directory with space"
a.txt b.txt
[root@localhost javatest]#
谁能解释一下原因并给出解决方法?
exec
有两个版本。
-
在这里,您可以使用与在命令行中类似的方式指定命令,即您需要用空格引用参数。
cmd /c dir "C:\Program Files"
-
此处单独指定参数,因此参数按原样给出,即不带引号。
exec
方法将处理参数中的任何空格和引号字符,根据需要正确引用和转义参数以执行命令。cmd /c dir C:\Program Files
因此,删除您添加的额外引号:
if (isWindows()) {
commandArray = new String[] { "cmd", "/c", "dir", "C:\Program Files"};
} else {
commandArray = new String[] { "ls", "/root/a directory with space"};
}