使用 processbuilder 加载所有环境变量

Loading all env variables with processbuilder

我想在从 java 代码执行脚本之前加载我在 .bashrc 文件中定义的变量。该脚本通过 ProcessBuilder 执行。在网上,我看到命令数组应该以 bash -c 开头,如下所示:

String[] cmdline = {"/bin/bash", "-c", "python", "/home/mahmood/temp.py"};
final ProcessBuilder pb = new ProcessBuilder(cmdline);
pb.command(cmdline);
pb.redirectOutput(Redirect.INHERIT);
final Process p = pb.start();
int exitCode = p.waitFor();
if (exitCode != 0) {
   throw new IOException("... python failed :( \n");
}

确实 waitFor 从来没有 returns!如果我删除 bash -c,那么 exitCode 将是非零的,因为尚未加载变量。

请注意.bashrc 中没有一个变量。我可以用 ProcessBuilder 解决问题还是有更好的选择?

另一种方法是手动添加环境变量作为 ProcessBuilder 环境的一部分。

例如,假设我们已将所需的环境变量存储在字符串数组 envVars 中,以下代码段将添加环境变量作为 ProcessBuilder 环境的一部分:

ProcessBuilder pb = new ProcessBuilder(Arrays.asList("python", "temp.py"));
pb.directory(new File("/home/mahmood/"));
Map<String, String> env = pb.environment();
Map<String, String> envToReproduce = new HashMap<String, String>();
for(int x=0;x<envVars.length;x++){
    System.out.println(envVars[x]);
    String[] tempEnv = envVars[x].split("=");
    if(tempEnv.length>1){                           
        String envVal = tempEnv[1].replaceAll("'","");
        envToReproduce.put(tempEnv[0], envVal);
        env.put(tempEnv[0], envVal);
    }
}

Bash 必须 作为交互式 shellread and execute commands from ~/.bashrc 调用。当 运行ning bash -c command 时,您正在非交互式 shell 中执行 command。要以交互方式 运行(并阅读 .bashrc),只需添加 -i:

String[] cmdline = {"/bin/bash", "-ic", "python /home/mahmood/temp.py"};

此外,请注意命令字符串 (python /path/to/file) 必须指定为 单字 (从 shell 调用时请注意单引号) :

bash -ic 'python /home/mahmood/temp.py'

否则,bash 将执行 python(第一个词)交互(而不是 运行ning 脚本)——并且这就是你的 waitFor 从未 returns.

的原因

由于 运行仅仅为了从 .bashrc 加载一些环境变量而使用交互式 shell 可能有点矫枉过正,您可以 提取感兴趣的变量单独的文件,例如:

export var1=val1
export var2='val 2'
...

然后那个文件就在运行宁之前你的python脚本:

String[] cmdline = {"/bin/bash", "-c", ". /path/to/envfile; python /home/mahmood/temp.py"};