Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用processbuilder加载所有环境变量_Java_Bash_Processbuilder - Fatal编程技术网

Java 使用processbuilder加载所有环境变量

Java 使用processbuilder加载所有环境变量,java,bash,processbuilder,Java,Bash,Processbuilder,我想在从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.redirect

我想在从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解决这个问题吗?或者有更好的选择吗?

另一种方法是手动添加环境变量,作为
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);
    }
}
ProcessBuilder pb=newprocessbuilder(Arrays.asList(“python”、“temp.py”);
pb.directory(新文件(“/home/mahmood/”);
Map env=pb.environment();
Map envroreproduct=new HashMap();
对于(int x=0;x1){
字符串enval=tempEnv[1]。replaceAll(“,”);
envroreproduct.put(tempEnv[0],envVal);
环境put(临时环境[0],环境值);
}
}

Bash
必须作为交互式shell调用,以执行以下操作。当运行
bash-c命令时,您正在非交互式shell中执行
command
。要以交互方式运行(并读取
.bashrc
),只需添加
-i

String[] cmdline = {"/bin/bash", "-ic", "python /home/mahmood/temp.py"};
另外,请注意,命令字符串(
python/path/to/file
)必须指定为单个单词(从shell调用时请注意单引号):

否则,
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"};

我看到
pb.environment()
返回的内容与我的bashrc不同。我正在用Netbeans进行调试,所以我认为当Netbeans执行时,它不会读取bashrc,因此用户定义的变量被忽略。这意味着,使用Netbeans比我想象的要困难得多!为了测试提出的想法,我必须从终端运行和调试。谢谢。虽然第一个方法运行了脚本,但我看到在执行了
pb.start()
之后,这些行被打印在输出窗口
bash:cannotset-set-process-group(1615):设备的ioctl不合适
bash:no-job-control在此shell中
,使用
-ic
“-c”有什么区别。“source~/.bashrc;python…”
?您看到这条消息是因为您运行Bash作为,但没有连接终端(因为您从Java运行它)。InteractiveShell运行起来有点“重”(请参阅),这就是为什么第二种方法可能更可取的原因。在第二种方法中,Bash是在非交互模式下运行的,但在执行Python脚本之前,我们首先获取环境变量的源代码(
-ic
-i-c
的编写方法一样简单);python…“
(除了您没有使用第二个表达式运行交互式shell之外)是您的
.bashrc
如果没有在交互式shell中运行,可能会过早退出—请检查
.bashrc
的开头,并查找类似以下内容:
[-z“$PS1”]&&return
。如果您修改
.bashrc
使其在非交互式shell中源代码时不退出,例如仅保留env vars,那么您正在接近答案中的第二个方法。谢谢。事实上,我从这次问答中学到了很多关于壳牌的东西,但我现在还没有注意到!
String[] cmdline = {"/bin/bash", "-c", ". /path/to/envfile; python /home/mahmood/temp.py"};