使用processbuilder加载所有env变量

时间:2017-11-22 11:28:02

标签: java bash processbuilder

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

bash -c

确实,waitFor永远不会回来!如果我删除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"); } ,那么bash -c将不为零,因为尚未加载变量。

请注意.bashrc中没有单个变量。我可以使用ProcessBuilder修复问题,还是有更好的选择?

2 个答案:

答案 0 :(得分:5)

Bash必须作为交互式shell 调用read and execute commands from ~/.bashrc。运行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(第一个单词)以交互方式(不运行脚本) - 这就是您waitFor永远不会的原因回报。

由于运行交互式shell只是为了从.bashrc加载一些环境变量可能是一种过度杀伤,你可以在一个单独的文件中提取感兴趣的变量,例如:

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

然后来源该文件只有才能运行您的python脚本:

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

答案 1 :(得分:1)

另一种方法是手动添加环境变量作为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);
    }
}