代码之家  ›  专栏  ›  技术社区  ›  mahmood

使用processbuilder加载所有环境变量

  •  2
  • mahmood  · 技术社区  · 7 年前

    我想加载我在中定义的变量。从java代码执行脚本之前的bashrc文件。该脚本通过ProcessBuilder执行。在web上,我看到命令数组应该从 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");
    }
    

    事实上,等待永远不会回来!如果我放下 bash-c ,然后 exitCode 将为非零,因为尚未加载变量。

    请注意,中没有一个变量。bashrc。我可以用ProcessBuilder解决这个问题吗?或者有更好的选择吗?

    2 回复  |  直到 7 年前
        1
  •  7
  •   randomir    7 年前

    Bash 必须是 作为交互式shell调用 read and execute commands from ~/.bashrc . 运行时 bash -c command 你正在执行 command 在非交互式shell中。以交互方式运行(并读取 .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'
    ...
    

    然后 来源 那个文件刚刚 运行前 你的 蟒蛇 脚本:

    String[] cmdline = {"/bin/bash", "-c", ". /path/to/envfile; python /home/mahmood/temp.py"};
    
        2
  •  1
  •   bprasanna    7 年前

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