【问题标题】:java process builder add path to environment not workingjava process builder添加到环境的路径不起作用
【发布时间】:2016-12-21 12:58:28
【问题描述】:

我在使用 processbuider 添加到进程环境的路径时遇到问题。我不知道为什么该过程忽略了环境。这是我的例子:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Map;


public class main {

    public static void main(String [ ] args) {
         try {
            String s = null;


            ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "fsl");
            Map<String, String> env;
            env = pb.environment();
            env.put("FSLDIR", "/usr/local/fsl/bin/");

            Process p = pb.start();

            BufferedReader stdInput = new BufferedReader(new
                    InputStreamReader(p.getInputStream()));

            BufferedReader stdError = new BufferedReader(new
                    InputStreamReader(p.getErrorStream()));

            System.out.println("Process p:");

            // read the output from the command
            while ((s = stdInput.readLine()) != null) {
                System.out.println(s);
            }
            while ((s = stdError.readLine()) != null) {
                System.out.println(s);
            }

            //////////*********\\\\\\\\\\\

            ProcessBuilder pb2 = new ProcessBuilder("/usr/local/fsl/bin/fsl");

            s = null;
            Process p2 = pb2.start();

            stdInput = new BufferedReader(new
                    InputStreamReader(p2.getInputStream()));

            stdError = new BufferedReader(new
                    InputStreamReader(p2.getErrorStream()));

            System.out.println("Process p2:");

            // read the output from the command
            while ((s = stdInput.readLine()) != null) {
                System.out.println(s);
            }
            while ((s = stdError.readLine()) != null) {
                System.out.println(s);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

输出:

Process p:

/bin/bash: fsl: command not found

Process p2:

DISPLAY is not set. Please set your DISPLAY environment variable!

您看到 FSL 想要设置更多变量。这就是为什么 p2 不是一个选项的原因。

【问题讨论】:

  • 您在the process is ignoring the environment 中谈论的环境是什么?
  • 它的 pb.environment() System.out.println(env);实际上表明该目录已添加
  • 进程p报错是合乎逻辑的,因为bash找不到命令和fsl。 FSLDIR=/usr/local/fsl/bin/ 之类的东西对 bash 的行为没有影响 -- 必须更改 PATH 变量才能使 bash 找到 fsl 命令。
  • 感谢 Jdamian,它成功了。

标签: java bash processbuilder


【解决方案1】:

正如 Jdamian 所说,Bash 搜索 PATH environment variable 中的目录以查找二进制文件 - Bash 不会查找您的 FSLDIR 变量,也不会将任意变量的值视为可执行文件。

当遇到进程库问题(例如,Java 中的 ProcessBuilder,Python 中的 subprocess)时,您应该始终做的第一件事是尝试直接在 shell 中复制问题。如果您在 shell 中运行 fsl 或 /bin/bash -c fsl,您可能会看到相同的错误(如果不这样做,您运行 Java 二进制文件的方式与您的 shell 不同),这确认问题与Java。

一旦您确认这只是如何修复它的问题。如果您希望 fsl 始终可用,请将其包含目录添加到您的 ~/.bashrc 文件中的 PATH 中:

export PATH="$PATH:/usr/local/fsl/bin"

如果您只想在 Java 二进制文件中使用它,请修改 PATH in-process:

// notice there's no need for `bash -c`
ProcessBuilder pb = new ProcessBuilder("fsl");
pb.environment().put("PATH",
                     "/usr/local/fsl/bin" + File.pathSeparator + System.getenv("PATH"));

然而,在实践中,如果您不修改 PATH 而是始终通过其绝对路径调用外部进程,您的代码通常会更易于维护和使用,就像您的第二个示例一样:

ProcessBuilder pb = new ProcessBuilder("/usr/local/fsl/bin/fsl");

这两个命令(大致)是等效的,但后者更清晰,并且不太可能引入令人困惑的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-06
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多