1

I'am writing Java console application which takes input parameters from environment variables (Linux). To set these variables, my application must "source" the shell script. 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.

There is my shell script (set_env.sh):

#!/bin/csh

setenv MY_DB DB_NAME

There is Java code to "source" the script above:

    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?

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.

anton_l
  • 11
  • 3
  • Not sure I get it. Would you post some code showing what you have done and where you are stuck? – Shlublu Jul 25 '14 at 08:16
  • 2
    This is a really poor piece of design. You should write a wrapper script that sources the shell script and then executes your Java program. It's not Java's business or the application's to be implementing shell syntax and semantics. – user207421 Jul 25 '14 at 08:26

2 Answers2

2

You can access the environment variables with System#getenv() and System#getenv(String name).

From the Oracle's tutorial:

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.

If you only aims to set a few variables used by your java code, java Properties are probably better suited.

NiziL
  • 5,068
  • 23
  • 33
  • As I understand, System.env is initialized during JVM startup and it can not be modified during application lifetime. – anton_l Jul 25 '14 at 08:34
  • 2
    @anton_l: Yes ! More exactly a child process can never modify the environment of its parent so if your JVM starts a shell, the shell can modify its own environment (and the one of its enventual descendants ...) but JVM's one will never be changed. – Serge Ballesta Jul 25 '14 at 10:19
1

How can I get access to created MY_DB variable or is there any other solution of my problem?

You can't. When you "source" your file, it is in fact read by the sub-shell you launched. The environment of this sub-shell is modified. 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. Yes and No. The Java standard libraries don't provide the necessary calls to change the current environment. 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. 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? See How do I set environment variables from 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

Community
  • 1
  • 1
Sylvain Leroux
  • 50,096
  • 7
  • 103
  • 125