Read environment variables from an application[转]

本文介绍了在Java中获取环境变量的不同方法,包括通过System.getProperty()读取预定义的属性,以及通过调用操作系统命令来获取所有环境变量。
从应用程序获取环境变量Read environment variables from an application

 

NOTE: JDK1.5 or better provides a simpler way to achieve this, see this HowTo .

JDK up to 1.4
Start the JVM with the "-D" switch to pass properties to the application and read them with the System.getProperty() method.

SET myvar=Hello world
SET myothervar=nothing
java -Dmyvar="%myvar%" -Dmyothervar="%myothervar%" myClass

then in myClass

String myvar = System.getProperty("myvar");
String myothervar = System.getProperty("myothervar");

If you don't know in advance, the name of the variable to be passed to the JVM, then there is no 100% Java way to retrieve them.


One approach (not the easiest one), is to use a JNI call to fetch the variables, see this HowTo .


A more low-tech way, is to launch the appropriate call to the operating system and capture the output. The following snippet puts all environment variables in a Properties class and display the value the TEMP variable.

import java.io.*;
import java.util.*;

public class ReadEnv {
 public static Properties getEnvVars() throws Throwable {
  Process p = null;
  Properties envVars = new Properties();
  Runtime r = Runtime.getRuntime();
  String OS = System.getProperty("os.name").toLowerCase();
  // System.out.println(OS);
  if (OS.indexOf("windows 9") > -1) {
    p = r.exec( "command.com /c set" );
    }
  else if ( (OS.indexOf("nt") > -1)
         || (OS.indexOf("windows 2000") > -1 )
         || (OS.indexOf("windows xp") > -1) ) {
    // thanks to JuanFran for the xp fix!
    p = r.exec( "cmd.exe /c set" );
    }
  else {
    // our last hope, we assume Unix (thanks to H. Ware for the fix)
    p = r.exec( "env" );
    }
  BufferedReader br = new BufferedReader
     ( new InputStreamReader( p.getInputStream() ) );
  String line;
  while( (line = br.readLine()) != null ) {
   int idx = line.indexOf( '=' );
   String key = line.substring( 0, idx );
   String value = line.substring( idx+1 );
   envVars.setProperty( key, value );
   // System.out.println( key + " = " + value );
   }
  return envVars;
  }

  public static void main(String args[]) {
   try {
     Properties p = ReadEnv.getEnvVars();
     System.out.println("the current value of TEMP is : " +
        p.getProperty("TEMP"));
     }
   catch (Throwable e) {
     e.printStackTrace();
     }
   }
}

thanks to w.rijnders for the w2k fix.


An update from Van Ly :

I found that, on Windows 2003 server, the property value for "os.name" is actually "windows 2003." So either that has to be added to the bunch of tests or just relax the comparison strings a bit:

  
else if ( (OS.indexOf("nt") > -1)
  || (OS.indexOf("windows 2000") > -1 )
  || (OS.indexOf("windows 2003") > -1 )  // ok 
                                         // but specific to 2003
  || (OS.indexOf("windows xp") > -1) ) {
 
  
else if ( (OS.indexOf("nt") > -1)
  || (OS.indexOf("windows 20") > -1 )  // better, 
                                       // since no other OS would 
                                       // return "windows"
  || (OS.indexOf("windows xp") > -1) ) {

I started with "windows 200" but thought "what the hell" and made it "windows 20" to lengthen its longivity. You could push it further and use "windows 2," I suppose. The only thing to watch out for is to not overlap with "windows 9."


On Windows, pre-JDK 1.2 JVM has trouble reading the Output stream directly from the SET command, it never returns. Here 2 ways to bypass this behaviour.

First, instead of calling directly the SET command, we use a BAT file, after the SET command we print a known string. Then, in Java, when we read this known string, we exit from loop.

[env.bat]
@set
@echo **end

[java]
...
  if (OS.indexOf("windows") > -1) {
    p = r.exec( "env.bat" );
    }
...

  while( (line = br.readLine()) != null ) {
   if (line.indexOf("**end")>-1) break;
   int idx = line.indexOf( '=' );
   String key = line.substring( 0, idx );
   String value = line.substring( idx+1 );
   hash.put( key, value );
   System.out.println( key + " = " + value );
   }

The other solution is to send the result of the SET command to file and then read the file from Java.

...
if (OS.indexOf("windows 9") > -1) {
    p = r.exec( "command.com /c set > envvar.txt" );
    }
else if ( (OS.indexOf("nt") > -1)
       || (OS.indexOf("windows 2000") > -1
       || (OS.indexOf("windows xp") > -1) ) {
    // thanks to JuanFran for the xp fix!
    p = r.exec( "cmd.exe /c set > envvar.txt" );
    }
...

// then read back the file
Properties p = new Properties();
      p.load(new FileInputStream("envvar.txt"));

Thanks to JP Daviau


 

// UNIX
public Properties getEnvironment() throws java.io.IOException {
    Properties env = new Properties();
    env.load(Runtime.getRuntime().exec("env").getInputStream());
    return env;
    }

Properties env = getEnvironment();
String myEnvVar = env.get("MYENV_VAR");

To read only one variable :

// NT version , adaptation for other OS is left as an exercise...
Process p = Runtime.getRuntime().exec("cmd.exe /c echo %MYVAR%");
BufferedReader br = new BufferedReader
     ( new InputStreamReader( p.getInputStream() ) );
String myvar = br.readLine();
System.out.println(myvar);

Java's System properties contains some useful informations about the environment, for example, the TEMP and PATH environment variables (on Windows).

public class ShowSome {
  public static void main(String args[]){
    System.out.println("TEMP : " 
      + System.getProperty("java.io.tmpdir"));
    System.out.println("PATH : " 
      + System.getProperty("java.library.path"));
    System.out.println("CLASSPATH : " 
      + System.getProperty("java.class.path"));
    System.out.println("SYSTEM DIR : " +
       System.getProperty("user.home")); // ex. c:\windows on Win9x
    System.out.println("CURRENT DIR: "  
      + System.getProperty("user.dir"));
    }
  }

Here some tips from H. Ware about the PATH on different OS.

PATH is not quite the same as library path. In unixes, they are completely different---the libraries typically have their own directories.

System.out.println("the current value of PATH is:  {" +
    p.getProperty("PATH")+"}");

System.out.println("LIBPATH:  {" +
   System.getProperty("java.library.path")+"}");

gives

the current value of PATH is:
{/home/hware/bin:/usr/local/bin:/usr/xpg4/bin:/opt/SUNWspro/bin:
 /usr/ucb:/bin:/usr/bin:/home/hware/linux-bin:/usr/openwin/bin/:
 /usr/local/games:/usr/ccs/lib/:/usr/new:/usr/sbin/:/sbin/:
 /usr/openwin/lib:/usr/X11/bin:/usr/bin/X11/:/usr/local/bin/X11:
 /usr/bin/pbmplus:/usr/etc/:/usr/dt/bin/:/usr/lib:
 /usr/lib/nis:/usr/share/bin:/usr/share/bin/X11:
 /home/hware/work/cdk/main/cdk/../bin:.}
LIBPATH:
{/usr/lib/j2re1.3/lib/i386:/usr/lib/j2re1.3/lib/i386/native_threads:
/usr/lib/j2re1.3/lib/i386/client:/usr/lib/j2sdk1.3/lib/i386:/usr/lib:/lib}

on my linux workstation. (java added all those except /lib and /usr/lib). But these two lines aren't the same on window either:

This system is windows nt

the current value of PATH is:
{d:\OrbixWeb3.2\bin;D:\jdk1.3\bin;c:\depot\cdk\main\cdk\bin;c:\depot\
cdk\main\cdk\..\bin;d:\OrbixWeb3.2\bin;D:\Program
Files\IBM\GSK\lib;H:\pvcs65\VM\win32\bin;c:\cygnus
\cygwin-b20\H-i586-cygwin32\bin;d:\cfn\bin;D:\orant\bin;
C:\WINNT\system32;C:\WINNT;
d:\Program Files\Symantec\pcAnywhere;
C:\Program Files\Executive Software\DiskeeperServer\;}
LIBPATH:
{D:\jdk1.3\bin;.;C:\WINNT\System32;C:\WINNT;D:\jdk1.3\bin;
c:\depot\cdk\main\cdk\bin;c:\depot\cdk\main\cdk\..\bin;
d:\OrbixWeb3.2\bin;D:\Program Files\IBM\GSK\lib;
H:\pvcs65\VM\win32\bin;c:\cygnus\cygwin-b20\H-i586-cygwin32\bin;d:\cfn\bin;
D:\orant\bin;C:\WINNT\system32;
C:\WINNT;C:\Program Files\Dell\OpenManage\ResolutionAssistant\Common\bin;
d:\Program Files\Symantec\pcAnywhere;
C:\Program Files\Executive Software\DiskeeperServer\;}

Java is prepending itself! That confused me--- and broke my exec from ant.

要注意,我是否只有这些命令。nvt@na51089: help ? - alias for ‘help’ base - print or set address offset bdinfo - print Board Info structure blkcache - block cache diagnostics and control bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol chpart - change active partition cmp - memory compare cp - memory copy crc32 - checksum calculation dhcp - boot image via network using DHCP/TFTP protocol env - environment handling commands exit - exit script false - do nothing, unsuccessfully fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) fatmkdir - create a directory fatrm - delete a file fatsize - determine a file’s size fatwrite - write file into a dos filesystem fdt - flattened device tree utility commands go - start application at address ‘addr’ gpio - query and control gpio pins help - print command description/usage httpd - httpd - start www server for firmware recovery loop - infinite loop on address range md - memory display md5sum - compute MD5 message digest mm - memory modify (auto-incrementing address) mmc - MMC sub system mmcinfo - display MMC info mtdparts - define flash/nand partitions mw - memory write (fill) nand - NAND sub-system nboot - boot from NAND device nm - memory modify (constant address) nvt_boot - To do nvt platform boot init. nvt_cpu_freq- change cpu freq nvt_encrypt- To encrypt via key manager sample nvt_get_cpu_freq- get cpu freq nvt_get_ddr_freq- get ddr freq/type nvt_jtag_disable- jtag disable nvt_key_set_engine_right- To read key set X nvt_read_key_set- To read key set X nvt_read_lock- To let key set X un-readable nvt_rtos_disable- To disable uboot boot rtos nvt_secure_en- secure enable related API nvt_uart_disable- To disable uart print nvt_write_key- To write key via OTP sample ping - send ICMP ECHO_REQUEST to network host printenv - print environment variables pwm - nvt pwm operation reset - Perform RESET of the CPU setenv - set environment variables showvar - print local hushshell variables test - minimal test like /bin/sh tftpboot - boot image via network using TFTP protocol true - do nothing, successfully ubi - ubi commands version - print monitor, compiler and linker version
最新发布
09-19
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值