How does the path environment variable work in Linux?

30,466

Solution 1

The basic concept to grasp here is that PATH can be defined in many places. As @demure explains in his answer, PATH=$PATH:/new/dir means add /new_dir to $PATH, it will not clear the original $PATH.

Now, one reason there are many files is intimately connected with the concept of login and non-login shells. See here for a nice summary. The following is from the bash man page (emphasis mine):

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

When you first log into your system, you start a login shell so bash will read the files listed above. Most distributions set a system-wide $PATH (which applies to all users) at /etc/profile and this is where you should make any changes that you want applied to all users. This is what I have on my Debian:

PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"

Once you have logged in, when you open a terminal you start an interactive, non-login shell. This is what man bash has to say about those:

   When  an  interactive shell that is not a login shell
   is started, bash reads  and  executes  commands  from
   /etc/bash.bashrc and ~/.bashrc, if these files exist.

So, those files are read every time you open a new terminal. Your filnal $PATH is the combination of the values in all files. In a typical situation, you log in using a graphical log in manager and start a new session. At this pòint your $PATH is whatever was defined in the various profile files. If you open a terminal, then you are in an interactive shell and the different bashrc files are read which may append things to the $PATH.


To summarize, all you really need to know is that you can make changes to your user's $PATH by editing $HOME/.profile.

Solution 2

In your home dir, it would be .bashrc, not .bash.rc.
The system wide config is /etc/bashrc not /etc/.bash.rc.

Unix and linux do not use \some\path\here file paths, they use /some/path/here file paths. \ is an escape character, and is used to disable other special characters.

You could edit your $PATH by adding these to lines to your ~/.bashrc (~ means your home dir)

PATH=$PATH:/usr/local/bin:/some/other/path
export PATH

Where

  • $PATH preserves anything already set to the PATH.
  • : separates entries.
  • And the two directories are examples (you don't need the :/some/other/path part)

I would not suggest editing your system wide /etc/bashrc if you only need changes for yourself.

Solution 3

First of all, the kernel (or initramfs) will supply an initial default PATH value for the init process, plus a few other environment variables. You can view them if you want:

$ sudo strings /proc/1/environ
selinux=0
SHLVL=1
HOME=/
init=/sbin/init
TERM=linux
drop_caps=
BOOT_IMAGE=/vmlinuz-4.9.80-atom
PATH=/sbin:/usr/sbin:/bin:/usr/bin
crashkernel=384M-:128M
PWD=/
rootmnt=/root

For daemons and other processes started at boot-up, the init process (whether a traditional SysVinit or one of the new replacements like systemd) may apply its own default PATH, or just pass through the kernel default value. This may or may not be configurable: see the documentation of your init system.

For login sessions, PAM settings might include pam_env.so which could enforce a default PATH for user sessions, configurable in /etc/security/pam_env.conf. Or if pam_env.so is not used, the process handling the login (e.g. sshd, or the traditional *getty+login pair on the console or serial port logins) might enforce their own default starting PATH for user sessions.

Then, the user's shell will typically execute one or more system-wide login scripts, and one or more user-specific login scripts if they exist. Any of these can add to the existing PATH setting or completely replace it.

Share:
30,466

Related videos on Youtube

diegoaguilar
Author by

diegoaguilar

Updated on September 18, 2022

Comments

  • diegoaguilar
    diegoaguilar over 1 year

    I'm confused how the PATH environment variable works under Linux. I'm a Linux Mint 15 user.

    First, I read about editing the /home/.bashrc file and doing a PATH=$PATH:/directory,
    but I also knew about some path stuff managed in /etc/bash.bashrc
    and so any software installed in /usr/local/bin would be reachable from anywhere in the shell.

    How does the path variable work under Linux and where should it be placed?

  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' almost 11 years
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' almost 11 years
  • terdon
    terdon almost 11 years
    @Gilles why? If you, for example, switch users with su, ~/.profile is not read while .bashrc is. Is it to avoid reloading the $PATH each time you open a new terminal?
  • demure
    demure almost 11 years
    @Gilles while I agree that the ~/.profile is a better choice, not everyone likes to bother with it
  • terdon
    terdon almost 11 years
    @Gilles ah, of course, that makes sense. OK, answer edited, thanks.
  • Ungeheuer
    Ungeheuer over 7 years
    Im new to linux and need to modify my PATH to contain the path for java jdk. Should this be a system wide or user specific change? No one else will be using my laptop either. you say ~/.profile is better to use than .bashrc, which one should a new user that doesnt know much about linux use?
  • demure
    demure over 7 years
    @Adrian both would affect only the user, /etc/profile would be for all users. ~/.bashrc only affects bash, ~/.profile affects all* shells. Just use the ~/.profile if you don't have a preference.