What are PATH and other environment variables, and how can I set or use them?

05
2014-04
  • Questioner

    Questions about

    • setting environment variables
    • the PATH

    are very common here, and in most cases the answers are very similar to each other. In the future it would be nice to have a good Q/A for this.

    So the question is: What are environment variables, like the executable PATH, and how can I change and use them on major operating systems?

    A good answer would include a simple explanation of what environment variables and especially PATH mean to the OS, as well as simple guidelines on how to set and read them accordingly.

  • Answers
  • see an example

    What are Environment Variables?

    Environment variables hold values related to the current environment, like the Operating System or user sessions.

    Path

    One of the most well-known is called PATH on Windows, Linux and Mac OS X. It specifies the directories in which executable programs* are located on the machine that can be started without knowing and typing the whole path to the file on the command line. (Or in Windows, the Run dialog in the Start Menu or Win+R).

    On Linux and Mac OS X, it usually holds all bin and sbin directories relevant for the current user. On Windows, it contains at least the C:\Windows and C:\Windows\system32 directories — that's why you can run calc.exe or notepad.exe from the command line or Run dialog, but not firefox.exe. (Firefox is located in C:\Program Files\Mozilla Firefox. For information on how to include Firefox, go here.)

    For example, typing calc (the .exe can be omitted) in the command line on Windows will start up the Windows Calculator.

    * You can add support for file extensions other than .exe by editing %PATHEXT%.

    Other

    Other variables might tell programs what kind of terminal is used (TERM on Linux/Mac OS X), or, on Windows, where the Windows folder is located (e.g. %WINDIR% is C:\Windows).

    Creating new environment variables

    In Windows, Linux and Unix, it's possible to create new environment variables, whose values are then made available to all programs upon launch.

    You can use this when writing scripts or programs that are installed or deployed to multiple machines and need to reference values that are specific to these machines. While a similar effect can be achieved using program-specific configuration settings, it's easier to do this using an environment variable if multiple programs need to access the same value.

     

    Windows

    GUI

    1. Open Control Panel » System » Advanced » Environment Variables.

    2. Type control sysdm.cpl,,3 in the Run dialog (Win+R) and click Environment Variables.
      For editing user variables you can also type %windir%\System32\rundll32.exe sysdm.cpl,EditEnvironmentVariables in the Run dialog.

    3. Right-click (My) Computer and click on Properties or simply press Win+Break.
      In XP click on Advanced » Environment Variables.
      In Vista+ click on Advanced system settings » Environment Variables.

    4. There are many other ways of reaching the same place, such as by typing "environment variables" in the Start Menu/Screen search box and so on.

    Environment variables in Windows are separated into user and machine/system specific values. You can view and edit their values there. Their current values upon launch are made available to all programs.

    There is also Rapid Environment Editor, which helps setting and changing environment variables in Windows without the need to go deep into the system settings. Another open source program for Windows with which the path environment can be edited very conveniently is Path Editor.

    Command Line

    Format

    Environment Variables in Windows are denoted with moduli surrounding the name:

    %name%
    

    echo

    To display an environment variable's value in cmd.exe, type echo %name%.

    C:\>echo %USERPROFILE%
    C:\Users\Daniel
    

    set

    To create/set a variable, use set varname=value:

    C:\>set FunnyCatPictures=C:\Users\Daniel\Pictures\Funny Cat Pictures
    
    C:\>set FunnyCatPicturesTwo=%USERPROFILE%\Pictures\Funny Cat Pictures 2
    

    To append/add a variable, use set varname=value;%varname%:

    C:\>set Penguins=C:\Windows
    
    C:\>set Penguins=C:\Linux;%Penguins%
    
    C:\>echo %Penguins%
    C:\Windows;C:\Linux
    

    setx

    To create/set a variable permanently, use setx varname "value":

    C:\>setx FunnyCatPictures "C:\Users\Daniel\Pictures\Funny Cat Pictures"
    
    [Restart CMD]
    
    C:\>echo %FunnyCatPictures%
    C:\Users\Daniel\Pictures\Funny Cat Pictures
    

    Unlike set, there is no equals sign and the path should be enclosed in quotes if it contains any spaces. Note that if %PATH% is included, there will be spaces, so it is best to include quotes around paths that contain any variables.

    You must manually add setx to versions of Windows earlier than Vista.
    Windows XP Service Pack 2 Support Tools

    List of Windows Environment Variables

    Here is a list of default environment variables 1, which are built into Windows. Some examples are: %WINDIR%, %WINDIR%, and %APPDATA%.

     

    Unix derivatives (FreeBSD, GNU / Linux, OS X)

    Environment Variables in Linux are prefixed with a dollar sign ($) such as $HOME or $HOSTNAME. Many well-known and standard variables are spelled out in capital letters to signify just that. Keep in mind that variable names are case sensitive meaning that $User and $USER are entirely unrelated from the shell's point of view.

    Unix derivatives define system wide variables in shell-scripts located mostly in the /etc folder, but user-specific values may be given to those variables in scripts located in the home folder (e.g /etc/profile, $HOME/.bash_profile). The .profile file in the home folder is a common place to define user variables.

    Setting variables

    These files are regular shell scripts and can contain more than just environment variable declarations. To set an environment variable, use export. To show your currently defined environment variables in a terminal, run env.

    The export command is a standard way to define variables. The syntax is very intuitive. The outcome is identical for these two lines.

    var=value; export var
    export var=value
    

    See the Linux documentation project, Path HOWTO for a more thorough discussion on this topic.

    Perhaps contrary to common belief, OS X is more "Unix" than Linux. Additionally to the files already mentioned, $PATH can be modified in these files:

    • /etc/paths contains all default directories that are added to the path, like /bin and /usr/sbin
    • Any file in /etc/paths.d — commonly used by installers to make the executable files they provide available from the shell without touching system wide or user specific configuration files. These files simply contain one path per line. e.g: /Programs/Mozilla/Calendar/bin.

     

    External Links:

    Environment Variables in XP
    Windows XP Service Pack 2 Support Tools (Includes setx)
    Environment Variables in Windows Vista and Windows 7
    Adding executables to the Run Dialog Box
    Mac OSX Tips - Setting Environment Variables
    TLDP: Path Howto

  • Area 51

    This post is from a more technical point of view than Daniel's, but doesn't explain as much the concepts.


    The Wikipedia article is also an excellent referrence.

    Linux and most BSDs

    In most command-line shells, temporary environment variables are set using export (sh, bash, zsh) or setenv (csh, tcsh) commands.

    • Examples for prepending $HOME/bin to $PATH in bash or zsh:

      export PATH="$HOME/bin:$PATH"
      

      (In this particular case, export is unnecessary since PATH is already part of the environment.)

    • csh, tcsh:

      setenv PATH "$HOME/bin:$PATH"
      

    Persistent environment variables can be set during several separate stages:

    • Login:

      • Login session setup: Linux pam_env, which usually reads from /etc/environment

      • Terminal logins: The shell's "profile" files.

        • bash uses /etc/profile and the first one of: ~/.bash_profile, ~/.bash_login, ~/.profile. Manual page bash(1) section Invocation.

          Often, the user's profile file includes an explicit call for ~/.bashrc too.

        • zsh: Manual page zsh(1) section Startup/shutdown files.

        • csh and other shells: See apropriate manual pages.

      • Graphical logins: Not sure; may vary depending on login manager. GDM appears to read ~/.profile in my system.

    • Opening of a terminal window:

      • bash uses /etc/bash.bashrc and ~/.bashrc.

    Windows NT series

    • In Command Prompt (cmd.exe), use set name=value to change environment variables for that window.

      To append c:\bin to %PATH%, use:

      set path=%path%;c:\bin
      

      This only affects that cmd.exe process, and any new processes launched from it.

    • To make persistent changes, use Control Panel → System → Advanced → Environment Variables. (docs)

      Note: While user settings normally override system ones, PATH variable is handled specially: both system and user settings are merged into the final value.

      Changes are stored to Registry (see below), and apply instantly to all new processes created by Explorer (the graphical shell), for example, through Start Menu.

    • System-wide environment variables are kept in the Registry, HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment, and loaded at system boot.

      User environment is kept in HKCU\Environment and loaded during user logon.

    • By default, the system also looks for set commands in AUTOEXEC.NT file.

    MS-DOS, 16-bit Windows, Windows 9x series

    • In MS-DOS Prompt (command.com), use set name=value, as in WinNT.

      Similarly, running set interactively only affects that one command.com instance, along with any new processes launched from it.

    • To make persistent changes, add or edit apropriate set lines in C:\AUTOEXEC.BAT, then reboot.

      • Workaround to avoid restarting, for Windows 9x: open a MS-DOS Prompt window, set the apropriate variables, close existing Explorer process (Start → Shut Down → while holding Ctrl+Shift, click Cancel), run explorer.exe from the MS-DOS Prompt window.

    VMS

    (Couldn't resist.)

    DCL has no concept of "path", but various symbol and command definitions can be put in SYS$LOGIN:LOGIN.COM.


  • Related Question

    command line - Best practice for Windows PATH/environment variables managing?
  • Justin L.

    Right now, it's such a mess. Every time I install a new program that does something trivial in the command line, I have to add it to the path. In fact, I'm developing on Ruby and even gems (plugins/extensions) sometimes have their own executables, and are stored in different folders and I end up having to add several paths per application, as well. It's gotten to the point that I am pushing thirty paths in my PATH environment variable.

    I'm cautious to copying and pasting them to a home folder of sorts and setting path to that; it just feels wrong. Is there an established best practice that I am missing?


  • Related Answers
  • Joey

    A number of small self-contained utilities reside in my %UserProfile%\Apps folder, such as archivers and the like. Then there are a number of batch files I wrote and frequently use which reside in %UserProfile%\Batches. For the rest, I just add them to the PATH, which is either done by an installer or with

    setx PATH "%PATH%;%CD%"
    

    from the appropriate directory. The number of paths there should probably only ever become an issue if the contents get too long (there are length limits for environment variables).

    You can (and I sometimes do) write small wrapper batch files for such programs. Simply copying/hardlinking/symlinking the executable into another directory will likely not work on Windows but you can easily create a batch file, for example for the program Foo:

    @"%ProgramFiles%\Foosoft Foo\foo.exe" %*
    

    and you can then add the folder where you store those batch files to your PATH.

  • ukanth

    I am not sure about any specific best practices. But I prefer using GUI PATH Editor tools to manage PATH variables. So that it can be clearly maintained.

    List of PATH Editor -

    Rapid Environment Editor

    Redmond PATH Editor

  • yzorg

    Now that most Windows machines come with PowerShell, I use many sal/Set-Alias commands in my user profile, so if an app has only one or two apps that I use I'll create aliases for just those two commands instead of adding the whole app folder to the path. Examples include SQL Management Studio, Notepad++, TFS Power Tools (command-line tool, tfpt.exe). I also copy my user profile across machines, so this lets me check for the existence of that app on the current machine before creating the alias (sometimes warning if app isn't installed).

    filter ctQuoteString { "`"$_`"" }
    filter ctResolvePath { Resolve-Path $_ | select -ExpandProperty Path | ctQuoteString } # used in Edit.ps1
    
    $nppExe = "C:\Program Files (x86)\Notepad++\notepad++.exe"
    if ((Test-Path variable:\nppExe) -and (Test-Path $nppExe)) {
        function EditNotepadPP { 
            param ([parameter(ValueFromPipelineByPropertyName=$true)][Alias("FullName","FileName")]$Path) 
            begin { if (! $nppExe) { throw 'variable $nppExe is not defined' } }
            process {
                $Path | ctResolvePath | % { # ctResolvePath will get full path and surround with quotes
                    & $nppExe $_
                }
                #AddEditHistory $Path #if you need detailed time tracking, might help to create a log what files you're editting
           } 
        }
        Set-Alias npp EditNotepadPP
    }
    
    # I have similar functions for other apps.
    Set-Alias vs EditVS
    Set-Alias tfe EditTFCheckout