简体   繁体   English

通过“源代码”从Java代码中设置和获取环境变量

[英]Setting and getting environment variables by “source” a shell script from Java code

I'am writing Java console application which takes input parameters from environment variables (Linux). 我正在编写Java控制台应用程序,它从环境变量(Linux)中获取输入参数。 To set these variables, my application must "source" the shell script. 要设置这些变量,我的应用程序必须“获取”shell脚本。 I can "source" the script by using Runtime.exec() or with ProcessBuilder, but I have no idea how to get access to created environment variables. 我可以使用Runtime.exec()或ProcessBuilder来“源”脚本,但我不知道如何访问创建的环境变量。

There is my shell script (set_env.sh): 有我的shell脚本(set_env.sh):

#!/bin/csh

setenv MY_DB DB_NAME

There is Java code to "source" the script above: 有上面的脚本“源代码”的Java代码:

    ProcessBuilder pb = new ProcessBuilder("csh", "-c", "'source set_env.sh'");
    Process p = null;
    try {
        p = pb.start();
        p.waitFor();
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    }

How can I get access to created MY_DB variable or is there any other solution of my problem? 如何访问创建的MY_DB变量或者是否有其他问题的解决方案?

Any help will be very appreciated. 任何帮助将非常感激。 Thank you in advance. 先感谢您。

Ok guys. 好了朋友们。 Thanks to your answers. 谢谢你的回答。 There is my temporary solution. 有我的临时解决方案。 I've written another script that makes "source" and echoes created variables. 我写了另一个脚本,使“源”和回声创建变量。 In the Java code I'am executing it, reading process's inputstream and parse them then. 在执行它的Java代码中,读取进程的输入流并解析它们。

You can access the environment variables with System#getenv() and System#getenv(String name) . 您可以使用System#getenv()System#getenv(String name)访问环境变量。

From the Oracle's tutorial : Oracle的教程

import java.util.Map;

public class EnvMap {
    public static void main (String[] args) {
        Map<String, String> env = System.getenv();
        for (String envName : env.keySet()) {
            System.out.format("%s=%s%n",
                              envName,
                              env.get(envName));
        }
    }
}

However, as mentioned by Sylvain Leroux and Serge Ballesta, the child process created with Process#start() can't modify the environment of its parents. 但是,正如Sylvain Leroux和Serge Ballesta所提到的,使用Process#start()创建的子进程无法修改其父Process#start()的环境。

If you only aims to set a few variables used by your java code, java Properties are probably better suited. 如果您只想设置java代码使用的一些变量,那么java Properties可能更适合。

How can I get access to created MY_DB variable or is there any other solution of my problem? 如何访问创建的MY_DB变量或者是否有其他问题的解决方案?

You can't. 你不能。 When you "source" your file, it is in fact read by the sub-shell you launched. 当您“获取”文件时,它实际上是由您启动的子shell读取的。 The environment of this sub-shell is modified. 修改了此子shell的环境。 But environment modification are not propagated back to the parent process. 但是环境修改不会传播回父进程。

As I understand, System.env is initialized during JVM startup and it can not be modified during application lifetime. 据我所知,System.env在JVM启动期间初始化,在应用程序生命周期内无法修改。 Yes and No. The Java standard libraries don't provide the necessary calls to change the current environment. 是和否.Java标准库不提供必要的调用来更改当前环境。 But don't imagine the the environment is somehow "locked". 但是不要想象环境会以某种方式“锁定”。 This is in fact more simple than that: Each process (shell, JVM instance, anything else) receives a copy of its parent environment upon creation. 事实上,这比这更简单:每个进程(shell,JVM实例,其他任何进程)在创建时都会收到其父环境的副本 You can do what you want with your copy, but as it is a copy, it is not connected in anyway with the environment of your parent. 您可以使用副本执行所需操作,但由于它副本,因此无论如何都不会与父项的环境相关联。 When you start a new process, it, in its turn, receives a copy of your environment at the moment of its creation. 当您启动新流程时,它会在创建环境时收到您环境的副本

As of the "missing" setEnv method in Java, this is maybe (?) because someone at Sun thought that would break the mantra "write once, run everywhere" as some systems don't have environment variables? 从Java中“缺失”的setEnv方法setEnv ,这可能是(?)因为Sun的某些人认为会打破“一次编写,随处运行”的咒语,因为有些系统没有环境变量? See How do I set environment variables from Java? 请参阅如何从Java设置环境变量?

BTW, If you need a custom environment to launch an external process, you might in fact build your own environment by using the second parameter of Runtime.html#exec 顺便说一句,如果您需要一个自定义环境来启动外部进程,您实际上可以使用Runtime.html #exec的第二个参数构建自己的环境

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM