使用 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
必须 作为交互式 shell 到 read 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"};
我想在从 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
必须 作为交互式 shell 到 read 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"};