What are Environment Variables?
Environment variables are global system variables accessible by all the processes/users running under the Operating System (OS), such as Windows, macOS and Linux. Environment variables are useful to store system-wide values, for examples,
PATH
: the most frequently-used environment variable, which stores a list of directories to search for executable programs.OS
: the operating system.COMPUTENAME
,USERNAME
: stores the computer and current user name.SystemRoot
: the system root directory.- (Windows)
HOMEDRIVE
,HOMEPATH
: Current user's home directory.
(Windows) Environment Variables
Environment Variables in Windows are NOT case-sensitive (because the legacy DOS is NOT case-sensitive). They are typically named in uppercase, with words joined with underscore (_
), e.g., JAVA_HOME
.
Display Environment Variables and their Values
To list ALL the environment variables and their values, start a CMD and issue the command "set
", as follows,
// Display all the variables (in NAME=VALUE pairs) set COMPUTERNAME=xxxxxxx OS=xxxxxxx PATH=xxxxxxx .......
Try issuing a "set
" command on your system, and study the environment variables listed. Pay particular attention to the variable called PATH
.
To display a particular variable, use command "set varname
", or "echo %varname%
":
// Display a particular variable set COMPUTERNAME COMPUTERNAME=xxxxxx // or, use "echo" command with variable name enclosed within a pair of '%' echo %COMPUTERNAME% COMPUTERNAME=xxxxxx
Set/Unset/Change an Environment Variable for the "Current" CMD Session
To set (or change) a environment variable, use command "set varname=value
". There shall be no spaces before and after the '='
sign. To unset an environment variable, use "set varname=
", i.e., set it to an empty string.
set varname set varname=value set varname= set |
Display the value of the variable Set or change the value of the variable (Note: no space before and after '=') Delete the variable by setting to empty string (Note: nothing after '=') Display ALL the environment variables |
For examples,
// Set an environment variable called MY_VAR set MY_VAR=hello // Display set MY_VAR MY_VAR=hello // Unset an environment variable set MY_VAR= // Display set MY_VAR Environment variable MY_VAR not defined
An environment variable set via the "set
" command under CMD is a local, available to the current CMD session only. Try setting a variable, re-start CMD and look for the variable.
Using an Environment Variable
To reference a variable in Windows, use %varname%
(with prefix and suffix of '%'
). For example, you can use the echo
command to print the value of a variable in the form "echo %varname%
".
// Display the PATH environment variable echo %PATH% PATH=xxxxxxx // Append a directory in front of the existing PATH set PATH=c:\myBin;%PATH% PATH=c:\myBin;[existing entries]
How to Add or Change an Environment Variable "Permanently"
To add/change an environment variable permanently in Windows (so that it is available to ALL the Windows' processes/users and stayed across boots):
- Launch "Control Panel"
- "System"
- "Advanced system settings"
- Switch to "Advanced" tab
- "Environment variables"
- Choose "System Variables" (for all users)
- To add a new environment variable:
- Choose "New"
- Enter the variable "Name" and "Value". Instead of typing the "value" and making typo error, I suggest that you use "Browse Directory..." or "Browse File..." button to retrieve the desired directory or file.
- To change an existing environment variable:
- Choose "Edit"
- Enter the new "Value". Instead of typing the "value" and making typo error, I suggest that you use "Browse Directory..." or "Browse File..." button to retrieve the desired directory or file.
You need to RE-START CMD for the new setting to take effect!
To verify the new setting, launch CMD:
set VAR_NAME
VAR_NAME=VAR_VALUE
PATH Environment Variable in Windows
When you launch an executable program (with file extension of ".exe
", ".bat
" or ".com
") from the CMD shell, Windows searches for the executable program in the current working directory, followed by all the directories listed in the PATH
environment variable. If the program cannot be found in these directories, you will get the following error:
// (Windows 2000/XP/Vista/7/8/10) "cmd.exe" abc 'abc' is not recognized as an internal or external command, operable program or batch file. // (Windows 95/98) "command.com" abc Bad command or file name
To list the current PATH
, issue command:
PATH
PATH=path1;path1;path3;...
How to Add a Directory to the PATH in Windows
To add a directory to the existing PATH
in Windows:
- Launch "Control Panel"
- "System"
- "Advanced system settings"
- Switch to "Advanced" tab
- "Environment variables"
- Under "System Variables" (for all users), select "Path"
- "Edit"
- (For newer Windows 10) A table pops up showing the directories included in the current PATH setting ⇒ "New" ⇒ "Browse..." to select the desired directory to be added to the PATH (Don't type as you will make typo error!) ⇒ Click "Move Up" repeatedly to move it to the top ⇒ "OK" (Don't "Cancel") ⇒ "OK" ⇒ "OK".
- (For older Windows) If you didn't see a pop-up table, it is time to change your computer.
You need to RE-START CMD for the new PATH setting to take effect!
To verify the new setting, launch CMD:
PATH
PATH=path1;path2;path3;...
Notes:
- Windows searches the current directory (
.
) before searching thePATH
entries. (Unixes/macOS does not search the current directory, unless you include it in the PATH explicitly.) - Windows uses semicolon (
;
) as the path separator; while Unixes/macOS uses colon (:
). - If your directory name contains special characters such as space (strongly not recommended), enclosed it with double quotes.
(macOS/Linux) Environment Variables
Environment variables in macOS/Unixes are case-sensitive. Global environment variables (available to ALL processes) are named in uppercase, with words joined with underscore (_
), e.g., JAVA_HOME
. Local variables (available to the current process only) are in lowercase.
Using Environment Variables in Bash Shell
Most of the Unixes (Ubuntu/macOS) use the so-called Bash shell. Under bash
shell:
- To list all the environment variables, use the command "
env
" (or "printenv
"). You could also use "set
" to list all the variables, including all local variables. - To reference a variable, use
$varname
, with a prefix'$'
(Windows uses%varname%
). - To print the value of a particular variable, use the command "
echo $varname
". - To set an environment variable, use the command "
export varname=value
", which sets the variable and exports it to the global environment (available to other processes). Enclosed the value with double quotes if it contains spaces. - To set a local variable, use the command "
varname
=value
" (or "set
varname
=value
"). Local variable is available within this process only. - To unset a local variable, use command "
varname
=
", i.e., set to empty string (or "unset
varname
").
How to Set an Environment Variable Permanently in Bash Shell
You can set an environment variable permanently by placing an export
command in your Bash shell's startup script "~/.bashrc
" (or "~/.bash_profile
", or "~/.profile
") of your home directory; or "/etc/profile
" for system-wide operations. Take note that files beginning with dot (.
) is hidden by default. To display hidden files, use command "ls -a
" or "ls -al
".
For example, to add a directory to the PATH
environment variable, add the following line at the end of "~/.bashrc
" (or "~/.bash_profile
", or "~/.profile
"), where ~
denotes the home directory of the current user, or "/etc/profile
" for ALL users.
// Append a directory in front of the existing PATH
export PATH=/usr/local/mysql/bin:$PATH
(For Java) You can set the CLASSPATH
environment variables by adding the following line. For example,
export CLASSPATH=.:/usr/local/tomcat/lib/servlet-api.jar
Take note that Bash shell uses colon (:
) as the path separator; while windows use semicolon (;
).
To refresh the bash shell, issue a "source
" command (or re-start the bash shell):
// Refresh the bash shell source ~/.bashrc // or source ~/.bash_profile source ~/.profile source /etc/profile
(Notes) For the older csh (C-shell) and ksh (Korn-shell)
- Use "
printenv
" (or "env
") to list all the environment variables. - Use "
setenv varname value
" and "unsetenv varname
" to set and unset an environment variable. - Use "
set varname=value
" and "unset varname
" to set and unset a local variable for the current process.
PATH Environment Variable
Most of the Unixes and macOS use the so-called Bash Shell in the "Terminal". When you launch an executable program (with file permission of executable) in a Bash shell, the system searches the program in ALL the directories listed in the PATH
. If the program cannot be found, you will get the following error:
abc
bash: abc: command not found
Take note that the current directory (.
) is not searched, unless it is included in the PATH
. To run a program in the current directory, you need to include the current path (./
), for example,
./myProgram
To list the current PATH
, issue command:
echo $PATH
path1:path2:path3:...
How to Add a Directory to the PATH in macOS/Linux
To add a directory to the existing PATH
in macOS/Unixes, add the following line at the end of one of the startup scripts, such as "~/.bashrc
", "~/.login
" "~/.bash_profile
", "~/.profile
" (where ~
denotes the home directory of the current user) or "/etc/profile
" for ALL users.
// Append a directory in front of the existing PATH export PATH=/path/to/dir:$PATH
To refresh the bash shell, issue a "source
" command (or re-start the bash shell):
// Refresh the bash shell source ~/.bashrc // or source ~/.bash_profile source ~/.profile source /etc/profile
To verify the new setting, launch CMD:
echo $PATH
path1:path2:path3:...
Notes:
- Unixes/macOS does not search the current directory (
.
), unless you include it explicitly in thePATH
. In other words, to run a program in the current directory, you need to provide the directory (./
), for example,./myProgram
You could include the current directory in thePATH
, by adding this line in a startup script:// Append the current directory (.) in front of the existing PATH export PATH=.:$PATH
(Windows searches the current directory (.
) automatically before searching the PATH.) - Unixes/macOS uses colon (
:
) as the path separator; while Windows uses semicolon (;
).
Java Applications and the Environment Variables PATH, CLASSPATH, JAVA_HOME
Many problems in the installation and running of Java applications are caused by incorrect setting of environment variables (global system variables available to all the processes/users running under the Operating System), in particular, PATH
, CLASSPATH
and JAVA_HOME
.
PATH
When you launch a program from the command line, the Operating System uses the PATH
environment variable to search for the program in your local file system. In other words, PATH
maintains a list of directories for searching executable programs.
PATH (For Windows)
When you launch an executable program (with file extension of ".exe
", ".bat
" or ".com
") from the CMD shell, Windows searches for the executable program in the current working directory, followed by all the directories listed in the PATH
environment variable. If the program cannot be found in these directories, you will get the following error:
// (Windows 2000/XP/Vista/7/8/10) "cmd.exe" abc 'abc' is not recognized as an internal or external command, operable program or batch file. // (Windows 95/98) "command.com" abc Bad command or file name
For example, if you are trying to use Java Compiler "javac.exe
" to compile a Java source file, but "javac.exe
" cannot be found in the current directory and all the directories in the PATH
, you will receive the following error:
javac Hello.java
'javac' is not recognized as an internal or external command,
operable program or batch file.
PATH
maintains a list of directories. The directories are separated by semicolon (;
) in Windows.
For Java applications, PATH
must include the following directories:
- JDK's "
bin
" (binary) directory (e.g., "c:\Program Files\java\jdk1.x.x\bin
"), which contains JDK programs such as Java Compiler "javac.exe
" and Java Runtime "java.exe
". - "
c:\windows\system32
" and "c:\windows
" which contain console programs and commands.
The JDK's "bin
" directory should be listed before "c:\windows\system32
" and "c:\windows
" in the PATH
. This is because some older Windows systems provide their own Java runtime (which is often outdated) in these directories (try search for "java.exe
" in your computer, you may find a few entries).
To add a directory (say JDK's "bin
") to the existing PATH, check "How to add a directory to the PATH".
PATH (For macOS/Linux)
Most of the Unixes and macOS use the so-called Bash Shell in the "Terminal". When you launch an executable program (with file permission of executable) in a Bash shell, the system searches the program in ALL the directories listed in the PATH
. If the program cannot be found, you will get the following error:
abc
bash: abc: command not found
For example, if you are trying to use Java Compiler "javac
" to compile a Java source file, but "javac
" can not be found in the list of directories in the PATH
, you will receive the following error:
javac Hello.java
bash: javac: command not found
To support Java applications, you need to include the JDK's "bin
" (binary) directory in the PATH. See "How to add a directory to the PATH".
CLASSPATH
Java Archive (JAR) File
For ease of distribution, Java classes are often archived (zipped) together into a so-called JAR file. To use a third-party Java package, you need to place the distributed JAR file in a location that is available to the Java Compiler and Java Runtime.
How Classes are Found?
Java Compiler ("javac
"), Java Runtime ("java
") and other Java tools searches for classes used in your program in this order:
- Java platform (bootstrap) classes: include system classes in core packages (
java.*
) and extension packages (javax.*
) in "rt.jar
" (runtime class), "i18n.jar
" (internationalization class),charsets.jar
,jre/classes
, and others. - Java Extension Directories: You can copy the external JAR files into Java Extension Directory (This is removed and not applicable from JDK 10).
- For Windows, the Java Extension Directory is located at "
<JAVA_HOME>\jre\lib\ext
" (e.g., "c:\Program Files\Java\jdk1.7.0_{xx}\jre\lib\ext
"). - For macOS, the JDK extension directories are "
/Library/Java/Extensions
" and "/System/Library/Java/Extensions
". - For Ubuntu, the JDK extension directories are "
<JAVA_HOME>/jre/lib/ext
" (e.g., "/usr/user/java/jdk1.7.0_{xx}/jre/lib/ext
") and "/usr/java/packages/lib/ext
".
java.ext.dirs
". You can print its contents viaSystem.out.println(System.getProperty("java.ext.dirs"))
. - For Windows, the Java Extension Directory is located at "
- User classes search path (in short, class path): determined in the following order:
- Defaulted to the current working directory (
.
). - Entries in the
CLASSPATH
environment variable, which overrides the default. - Entries in the
-cp
(or-classpath
) command-line option, which overrides theCLASSPATH
environment variable. - The runtime command-line option
-jar
, which override all the above.
java.class.path
".
It is recommended that you use the-cp
(or-classpath
) command-line option (customized for each of your applications), instead of setting a permanentCLASSPATH
environment for all the Java applications. IDE (such as Eclipse/NetBeans) manages-cp
(-classpath
) for each of the applications and does not rely on theCLASSPATH
environment. - Defaulted to the current working directory (
Cannot Find Classes
If the Java Runtime ("java
") cannot find the classes used in your program in all the above places, it will issue error "Could not find or load main class xxxx" (JDK 1.7) or "java.lang.NoClassDefFoundError" (Prior to JDK 1.7).
Similarly, Java Compiler ("javac
") will issue compilation errors such as "cannot find symbol", "package does not exist".
Notes: External native libraries (".lib
", ".dll
", ".a
", ".so
") are to be found in a path in JRE's Property "java.library.path
", which normally but not necessarily includes all the directories in the PATH
environment variable. Otherwise, you will get a runtime error "java.lang.UnsatisfiedLinkError: no xxx in java.library.path
".
CLASSPATH Environment Variable
The CLASSPATH
environment variable could include directories (containing many class files) and JAR files (a single-file archive of class files). If CLASSPATH
is not set, it is defaulted to the current directory. If you set the CLASSPATH
, it is important to include the current working directory (.
). Otherwise, the current directory will not be searched.
A common problem in running hello-world program is: CLASSPATH
is set but does not include the current working directory. The current directory is therefore not searched, which results in "Error: Could not find or load main class Hello". You can simply remove the CLASSPATH
, and leave the class path defaulted to the current directory.
For a beginner, no explicit CLASSPATH
setting is required. The default CLASSPATH
setting of current directory is sufficient. Remove all CLASSPATH
setting if there is any. However, if you have to set CLASSPATH
, make sure that you include the current directory '.'
.
The PATH
environment variable (for searching the executable programs) is applicable to all applications; while CLASSPATH
is used by Java only.
Read JDK documents "Setting the CLASSPATH
" and "How Classes are Found" (you can find the hyperlinks from the index page of the JDK documentation, or googling).
CLASSPATH Environment Variable (For Windows)
The CLASSPATH
accepts directories and jar-files. Path entries are separated by semicolon (;
).
Example: Displaying and changing CLASSPATH
for the current CMD session.
// Display current setting of CLASSPATH set CLASSPATH // Set CLASSPATH to the current directory and a JAR file set CLASSPATH=.;d:\tomcat\lib\servlet-api.jar
You can set the CLASSPATH
permanently. See "How to Set an Environment Variable".
CLASSPATH (for macOS/Ubuntu)
- To set the
CLASSPATH
for the current session, issue this command:export CLASSPATH=.:/usr/local/tomcat/bin/servlet-api.jar
Use colon ':
' as the path separator (instead of semicolon ';
' in Windows). - To set the
CLASSPATH
permanently, place the above export command in the bash shell initialization script (.bashrc
or.bash_profile
of the home directory or/etc/profile
for all users). See "How to Set an Environment Variable".
JAVA_HOME and JRE_HOME
Many Java applications (such as Tomcat) require the environment variable JAVA_HOME
to be set to the JDK installed directory.
How to Set JAVA_HOME in Windows
First, check if JAVA_HOME
is already set by start a CMD and issue:
set JAVA_HOME
If JAVA_HOME
is not set, you will receive "Environment variable JAVA_HOME not defined". Otherwise, the current setting will be shown.
To set/change JAVA_HOME
in Windows:
- Launch "Control Panel"
- "System"
- "Advanced system settings"
- Switch to "Advanced" tab
- "Environment variables"
- Choose "System Variables" (for all users)
- To add a new environment variable "
JAVA_HOME
":- Choose "New"
- In "Variable Name", enter "JAVA_HOME".
- In "Variable Value", click "Browse Directory..." and navigate to the JDK installed directory (e.g., "
C:\Program Files\Java\jdk-15.0.xx
"). - OK ⇒ OK ⇒ OK.
- To change the existing "
JAVA_HOME
" setting:- Select "
JAVA_HOME
" ⇒ "Edit" - In "Variable Value", click "Browse Directory..." and navigate to the JDK installed directory (e.g., "
C:\Program Files\Java\jdk-15.0.xx
"). - OK ⇒ OK ⇒ OK.
- Select "
You need to RE-START CMD for the new setting to take effect!
To verify the new setting, re-start CMD:
set JAVA_HOME
JAVA_NAME=C:\Program Files\Java\jdk-13.0.1
How to Set JAVA_HOME in Linux/macOS (Bash Shell)
First, check if JAVA_HOME
is already set by start a terminal and issue:
echo $JAVA_HOME
JAVA_HOME
is to be set to the JDK installed directory. You need to find your JDK installed directory.
[TODO] find macOS and Ubuntu JDK installed directory.
Add the the following line at the end of "~/.bashrc
" (or "~/.login
"). Take note that filename beginning with dot (.
) is hidden by default.
[TODO] How to un-hide for macOS/Ubuntu.
export JAVA_HOME=/path/to/JDK-installed-directory
You need to refresh the bash shell for the new settings to take effect. Issue a "source
" command as follows:
// Refresh the Bash Shell source ~/.bashrc // or "source ~/.login" // Verify the new setting echo $JAVA_HOME
Windows vs. Unixes/macOS
Java is platform independent. Java classes run in Windows as well as Unixes - binary compatible.
- Unixes have many shells, such as the newer
bash
and the oldercsh
,ksh
. Windows have two shells: the newercmd.exe
and the oldercommand.com
. Each shell come with its own set of commands, utilities, and its own scripting programming language. - Unix's variable name is denoted as
$varname
, e.g.,$CLASSPATH
. Windows uses%varname%
, e,g.,%CLASSPATH%
. - Unix uses command "
printenv
" (print environment) or "env
" to list all the environment variables. Windows uses command "set
". - Unix's
PATH
is set permanently in the login or shell initialization script (e.g., "~/.login
", "~/.profile
", "~/.bashrc
", "~/.bash_profile
", or "/etc/profile
"). Windows'PATH
is set permanently via Control Panel ⇒ System ⇒ .... - The current directory is NOT included in the Unix's
PATH
implicitly. To run a program in the current directory, you need to issue "./programName
" where ".
" denotes the current directory. It is recommended to include the current directory (.
) in thePATH
explicitly. On the other hand, current directory is included in Windows'PATH
implicitly. - A Windows' path includes a drive letter and directories. Each drive has a root directory. It uses back-slash
'\'
as directory separator (e.g., "c:\jdk1.6\bin
"). Linux's paths do not have drive letter. There is a single root. Unix uses forward slash'/'
as the directory separator (e.g., "/usr/bin/jdk1.6
"). - Windows use semicolon
';'
as path separator (e.g., inPATH
environment variable), while Unix uses colon':'
. - Windows/DOS uses "
0D0AH
" (carriage-return plus line-feed) as line-break (or End-of-Line (EOL), or newline). Unixes/macOS uses "0AH
" (line-feed) only.