Java Runtime exec()无法解析环境变量

时间:2020-06-03 03:13:03

标签: java linux exec

如果我在终端中运行以下命令,则会得到预期的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

我想念什么?

2 个答案:

答案 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组成,这就是它的输出。

有三种解决方法:

  1. 在Java中内插变量;例如

      String[] cmd = {"echo", "123"};
      Process p = Runtime.getRuntime().exec(cmd);
    

    或重复搜索/替换看起来像变量的内容。 (但这只涉及环境变量插值,而不涉及其他形式的外壳替换。)

  2. 假设您正在做的事情比echo更复杂,请编写您正在运行的命令以对其环境变量进行内插。 (这很笨拙……)

  3. 在shell中显式调用命令;例如

      String[] envp = {"FOO=123"};
      String[] cmd = {"/bin/sh", "-c", "echo $FOO"};
      Process p = Runtime.getRuntime().exec(cmd, envp);
    

    请注意,您可以使用任何shell,并提供几乎可以在单个shell命令行中表达的任何shell行为。