在Windows批处理(cmd.exe)中从文件读取环境变量

19

我正在尝试从批处理文件中读取变量,以便在稍后的批处理脚本中使用,这是一个Java启动器。 我希望在所有平台(Unix、Windows)上都具有相同的设置文件格式,并且还是有效的Java属性文件。也就是说,它应该看起来像这样:

setting1=Value1
setting2=Value2
...

是否可以像在Unix shell脚本中一样读取这样的值?代码应该类似于:

能不能像在Unix shell脚本中那样读取这样的值?代码应该长成这样:

Is it possible to read such values like you would in a Unix shell script? The could should look something like this:
READ settingsfile.xy
java -Dsetting1=%setting1% ...

我知道使用SET setting1=Value1可能是可以实现的,但我真的希望所有平台上的设置都使用相同的文件格式。

澄清一下:我需要在命令行/批处理环境中进行此操作,因为我还需要设置无法从JVM内部更改的参数,如-Xmx或-classpath。

6个回答

40
你可以在批处理文件中这样做:

你可以在批处理文件中这样做:

setlocal
FOR /F "tokens=*" %%i in ('type Settings.txt') do SET %%i
java -Dsetting1=%setting1% ...
endlocal

该代码读取一个包含类似于“SETTING1=VALUE1”的字符串的文本文件,并调用SET函数将它们设置为环境变量。

setlocal/endlocal用于限制环境变量的作用范围,仅在批处理文件执行期间使用。

CMD命令处理器实际上相当强大,但其语法有些复杂。


经过长时间的寻找,我找到了这个解决方案。谢谢! - Pereira
1
你如何忽略一个“注释”(例如,以“#”字符开头的行)-? - malthe
1
@malthe - 一种方法就是忽略注释行产生的任何错误消息,或者隐藏它们,例如 FOR /F "tokens=*" %%i in ('type Settings.txt') do SET %%i 2> NUL: - Joe
3
@malthe - 添加 _eol=<注释字符>_。FOR /F "tokens=* eol=#" %%i in ('type Settings.txt') do SET %%i - shurkam

2
您可以将属性文件作为参数传递给Java程序(该程序稍后可能会启动主程序)。然后从多平台范例中受益。

是的,那通常是正确的,但我还需要配置像-Xmx这样的东西,当然一旦JVM运行起来就不能更改了。 - Martin Probst
哦,我明白了,与解决方案相比,这听起来有些过度,但您可以从另一个Java重新启动Java。不要误解我的意思,我确实更喜欢所选的解决方案。 - call me Steve

1
可能明智的做法是从属性文件中仅导入特定变量(您预先了解的变量),在这种情况下,我建议使用以下函数:
:parsePropertiesFile
    set PROPS_FILE=%1
    shift
    :propLoop
    if "%1"=="" goto:eof
    FOR /F "tokens=*" %%i in ('type %PROPS_FILE% ^| findStr.exe "%1="') do SET %%i
    shift
    GOTO propLoop
goto:eof

通过 call:parsePropertiesFile props.properties setting1 setting2 调用,以设置变量 setting1 和 setting2。


1

这段代码将会执行以下操作:

  • 跳过所有以 # 开头的行(可以用于注释)
  • 读取与批处理脚本在同一目录下的 .env 文件,并将其传递给 SET

脚本代码:

FOR /F "eol=# tokens=*" %%i IN (%~dp0.env) DO SET %%i

如果您希望将变量作为数字读取,则需要在.env文件中的变量行前加上/A标志
例如:/A PORT=1215 为了更有帮助,这是我正在解析的.env文件
# The name of the mariadb service to be installed
MariaDb_serviceName=Swoole_MariaDB
# which port the mariadb server will run at
# notice i added /A flag so that the SET command stores the variable as a number
/A MariaDb_port=1214
# password of mariadb root user
MariaDb_rootPassword=
# Database to be created after installing mariadb
MariaDb_createDataBase=data
# the server service name to be installed
Server_serviceName=Swoole_Server

2
不需要使用/a,因为批处理只知道一种变量类型:STRING。set /a用于将字符串转换为整数进行算术运算,并再次将字符串分配给变量。 - Stephan

0

你也可以从Java程序中访问操作系统环境变量:

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

0

这个一行代码在将值赋给变量之前也会取消引用:

for /F "delims== tokens=1,* eol=#" %%i in (%filename%) do set %%i=%%~j
  • delims== 按照 = 字符进行行拆分
  • tokens=1,* 将第一个 token(名称)放入 %%i 中,将剩余部分(值)放入 %%j
  • eol=# 跳过以 # 开头的行(注释)
  • %%~j 从值中删除周围的引号

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接