如果我在终端中运行以下命令,则会得到预期的123
$ /bin/sh
$ FOO=123
$ echo $FOO
123
现在,我尝试对Java的Runtime's exec()执行以下操作:
String[] envp = { "FOO=123" };
String cmd = "echo $FOO";
Process p = Runtime.getRuntime().exec(cmd, envp);
java.io.BufferedReader reader =
new java.io.BufferedReader(
new java.io.InputStreamReader(p.getInputStream()
)
);
System.out.println(reader.readLine());
我希望看到123
,但我得到$FOO
。
我想念什么?
答案 0 :(得分:0)
以下内容适用于Windows。
String[] envp = { "FOO=123" };
String cmd = "cmd /c echo %FOO%";
Process p = Runtime.getRuntime().exec(cmd, envp);
p.waitFor();
java.io.BufferedReader reader =
new java.io.BufferedReader(
new java.io.InputStreamReader(p.getInputStream()
)
);
String line;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
答案 1 :(得分:0)
我想念什么?
首先,
$ FOO=123
设置一个shell变量。它是外壳程序的本地文件。如果希望变量位于子进程看到的环境中,则必须export
。
$ export FOO=123
但这不是问题。
真正的问题是命令字符串"echo $FOO"
。问题是$FOO
是外壳语法....但是当您使用exec
从Java运行命令时:
exec
本身不了解shell语法,并且exec
不在外壳中运行命令。因此,给echo
命令赋予的参数由文字字符串$FOO
组成,这就是它的输出。
有三种解决方法:
在Java中内插变量;例如
String[] cmd = {"echo", "123"};
Process p = Runtime.getRuntime().exec(cmd);
或重复搜索/替换看起来像变量的内容。 (但这只涉及环境变量插值,而不涉及其他形式的外壳替换。)
假设您正在做的事情比echo
更复杂,请编写您正在运行的命令以对其环境变量进行内插。 (这很笨拙……)
在shell中显式调用命令;例如
String[] envp = {"FOO=123"};
String[] cmd = {"/bin/sh", "-c", "echo $FOO"};
Process p = Runtime.getRuntime().exec(cmd, envp);
请注意,您可以使用任何shell,并提供几乎可以在单个shell命令行中表达的任何shell行为。