繁体   English   中英

Java 运行时 exec() 不解析环境变量

[英]Java Runtime exec() does not resolve environment variable

如果我在终端中运行以下命令,我会得到预期的123

$ /bin/sh
$ FOO=123
$ echo $FOO
123

现在我尝试使用 Java 的Runtime 的 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

我错过了什么?

以下在 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);
}

我错过了什么?

首先,

$ FOO=123

设置 shell 变量。 它是 shell 本地的。 如果您希望变量处于子进程看到的环境中,则必须将其export

$ export FOO=123

但这不是问题。

真正的问题是命令字符串"echo $FOO" 问题是$FOO是 shell 语法....但是当您使用exec从 Java 运行命令时:

  • exec本身不理解 shell 语法,并且
  • exec不会在 shell 中运行该命令。

因此,提供给echo命令的参数由文字字符串$FOO ... 组成,这就是它输出的内容。

解决这个问题的方法有以下三种:

  1. 对Java中的变量进行插值; 例如

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

    或者通过重复搜索/替换看起来像变量的东西。 (但这仅涉及环境变量插值,而不涉及 shell 替换的其他 forms。)

  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-ism。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM