【问题标题】:Setting and getting environment variables by "source" a shell script from Java code通过从 Java 代码中“获取”一个 shell 脚本来设置和获取环境变量
【发布时间】:2014-07-25 08:14:19
【问题描述】:

我正在编写 Java 控制台应用程序,它从环境变量 (Linux) 中获取输入参数。要设置这些变量,我的应用程序必须“获取”shell 脚本。我可以使用 Runtime.exec() 或 ProcessBuilder“获取”脚本,但我不知道如何访问创建的环境变量。

有我的shell脚本(set_env.sh):

#!/bin/csh

setenv MY_DB DB_NAME

有 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();
    }

我如何才能访问创建的 MY_DB 变量,或者我的问题有其他解决方案吗?

任何帮助将不胜感激。 先感谢您。

好的,伙计们。感谢您的回答。有我的临时解决方案。我编写了另一个脚本,它生成“源”并回显创建的变量。在 Java 代码中,我正在执行它,读取进程的输入流并解析它们。

【问题讨论】:

  • 不知道我明白了。你会发布一些代码来显示你做了什么以及你卡在哪里了吗?
  • 这是一个非常糟糕的设计。您应该编写一个包装脚本来获取 shell 脚本,然后执行您的 Java 程序。实现 shell 语法和语义不是 Java 或应用程序的事情。

标签: java linux shell


【解决方案1】:

您可以使用System#getenv()System#getenv(String name) 访问环境变量。

来自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));
        }
    }
}

但是,正如 Sylvain Leroux 和 Serge Ballesta 所提到的,使用 Process#start() 创建的子进程无法修改其父进程的环境。

如果您只打算设置 java 代码使用的几个变量,java Properties 可能更适合。

【讨论】:

  • 据我了解,System.env 是在 JVM 启动期间初始化的,在应用程序生命周期内无法修改。
  • @anton_l:是的!更确切地说,子进程永远不能修改其父进程的环境,因此如果您的 JVM 启动 shell,shell 可以修改自己的环境(以及它的最终后代之一......),但 JVM 的环境永远不会改变。跨度>
【解决方案2】:

我如何才能访问创建的 MY_DB 变量,或者我的问题是否有其他解决方案?

你不能。当您“获取”您的文件时,它实际上是由您启动的子 shell 读取的。这个子shell的环境被修改了。但是环境修改不会传播回父进程。

据我了解,System.env 是在 JVM 启动期间初始化的,在应用程序生命周期内无法修改。 是和否。Java 标准库不提供更改当前环境所需的调用。但不要想象环境以某种方式“锁定”。这实际上比这更简单:每个进程(shell、JVM 实例、其他任何东西)在创建时都会收到其父环境的 副本。你可以对你的副本做任何你想做的事,但是因为它一个副本,它与你父母的环境没有任何联系。当您启动一个新进程时,它会在创建时收到您的环境的副本

对于 Java 中的“缺失”setEnv 方法,这可能是(?)因为 Sun 有人认为这会打破“一次编写,到处运行”的口头禅,因为某些系统没有环境变量?见How do I set environment variables from Java?

顺便说一句,如果您需要自定义环境来启动外部进程,您实际上可以使用Runtime.html#exec 的第二个参数来构建自己的环境

【讨论】:

    猜你喜欢
    • 2015-07-26
    • 2016-12-23
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    相关资源
    最近更新 更多