java进程生成器添加环境无法正常工作的路径

时间:2016-12-21 12:58:29

标签: java bash processbuilder

我在使用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不是一个选项。

1 个答案:

答案 0 :(得分:1)

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

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

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

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

如果您只想在Java二进制文件中使用它,请修改进程中的PATH

// 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而只是总是通过绝对路径调用外部进程,那么代码通常会更易于维护和使用,就像第二个例子一样:< / p>

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

这两个命令(大致)是等价的,但后者更清晰,不太可能引入混乱的错误。