如何从Java中设置环境变量?我发现我可以使用ProcessBuilder为子流程做到这一点。不过,我有几个子流程要启动,所以我宁愿修改当前流程的环境,让子流程继承它。
有一个System.getenv(String)用于获取单个环境变量。我还可以使用System.getenv()获得完整环境变量集的Map。但是,在该Map上调用put()会抛出UnsupportedOperationException——显然,它们意味着环境是只读的。并且,没有System.setenv()。
那么,有没有办法在当前运行的进程中设置环境变量呢?如果有,怎么做?如果不是,理由是什么?(是不是因为这是Java,所以我不应该做邪恶的、不可移植的、过时的事情,比如触摸我的环境?)如果不是,有什么好的建议来管理我将需要提供给几个子流程的环境变量更改吗?
只需使用反射,比如setEnv("k1","v1")
private void setEnv(String key, String val) throws Exception {
getModifiableEnv().put(key, val);
}
private Map<String, String> getModifiableEnv() throws Exception {
Map<String, String> unmodifiableEnv = System.getenv();
Field field = unmodifiableEnv.getClass().getDeclaredField("m");
field.setAccessible(true);
return (Map<String, String>) field.get(unmodifiableEnv);
}
need
import java.lang.reflect.Field;
import java.util.Map;
蒂姆·瑞安的回答对我很管用……但我希望它用于Groovy(例如Spock上下文),并且simplissimo:
import java.lang.reflect.Field
def getModifiableEnvironmentMap() {
def unmodifiableEnv = System.getenv()
Class cl = unmodifiableEnv.getClass()
Field field = cl.getDeclaredField("m")
field.accessible = true
field.get(unmodifiableEnv)
}
def clearEnvironmentVars( def keys ) {
def savedVals = [:]
keys.each{ key ->
String val = modifiableEnvironmentMap.remove(key)
// thinking about it, I'm not sure why we need this test for null
// but haven't yet done any experiments
if( val != null ) {
savedVals.put( key, val )
}
}
savedVals
}
def setEnvironmentVars(Map varMap) {
modifiableEnvironmentMap.putAll(varMap)
}
// pretend existing Env Var doesn't exist
def PATHVal1 = System.env.PATH
println "PATH val1 |$PATHVal1|"
String[] keys = ["PATH", "key2", "key3"]
def savedVars = clearEnvironmentVars(keys)
def PATHVal2 = System.env.PATH
println "PATH val2 |$PATHVal2|"
// return to reality
setEnvironmentVars(savedVars)
def PATHVal3 = System.env.PATH
println "PATH val3 |$PATHVal3|"
println "System.env |$System.env|"
// pretend a non-existent Env Var exists
setEnvironmentVars( [ 'key4' : 'key4Val' ])
println "key4 val |$System.env.key4|"