简体   繁体   English

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

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

If I run the following in a terminal I get the expected 123如果我在终端中运行以下命令,我会得到预期的123

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

Now I try to do the following with Java's Runtime's exec() :现在我尝试使用 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());

I expect to see 123 but instead I get $FOO .我希望看到123但我得到$FOO

What am I missing?我错过了什么?

The following works under Windows.以下在 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);
}

What am I missing?我错过了什么?

Firstly,首先,

$ FOO=123

sets a shell variable.设置 shell 变量。 It is local to the shell.它是 shell 本地的。 If you want a variable to be in the environment that child processes see, you must export it.如果您希望变量处于子进程看到的环境中,则必须将其export

$ export FOO=123

But that's not the problem.但这不是问题。

The real issue is the command string "echo $FOO" .真正的问题是命令字符串"echo $FOO" The problem is that $FOO is shell syntax.... but when you run a command from Java using exec :问题是$FOO是 shell 语法....但是当您使用exec从 Java 运行命令时:

  • exec itself doesn't understand shell syntax, and exec本身不理解 shell 语法,并且
  • exec doesn't run the command in a shell. exec不会在 shell 中运行该命令。

So the parameter that is given to the echo command consists of the literal string $FOO ... and that is what it outputs.因此,提供给echo命令的参数由文字字符串$FOO ... 组成,这就是它输出的内容。

There are three approaches to solving this:解决这个问题的方法有以下三种:

  1. Interpolate the variable in Java;对Java中的变量进行插值; eg例如

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

    or by doing repeated search / replace for things that look like variables.或者通过重复搜索/替换看起来像变量的东西。 (But this only deals with environment variable interpolation, not other forms of shell substitution.) (但这仅涉及环境变量插值,而不涉及 shell 替换的其他 forms。)

  2. Assuming that you are doing something more complicated than echo , write the command that you are running to do its own interpolation of environment variables.假设您正在执行比echo更复杂的操作,请编写您正在运行的命令来执行自己的环境变量插值。 (This is clunky...) (这很笨拙……)

  3. Explicitly invoke the command in a shell;在 shell 中显式调用命令; eg例如

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

    Note that you can use any shell, and provide pretty much any shell-ism that can be expressed in a single shell command line.请注意,您可以使用任何 shell,并提供几乎任何可以在单个 shell 命令行中表达的 shell-ism。

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

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