Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers . If you believe the question would be on-topic on another Stack Exchange site , you can leave a comment to explain where the question may be able to be answered.

Closed 2 years ago .

The community reviewed whether to reopen this question last month and left it closed:

Original close reason(s) were not resolved

On Linux, how can I add a directory to the $PATH so it remains persistent across different sessions?

Background

I'm trying to add a directory to my path so it will always be in my Linux path. I've tried:

export PATH=$PATH:/path/to/dir

This works, however each time I exit the terminal and start a new terminal instance, this path is lost, and I need to run the export command again.

How can I do it so this will be set permanently?

If you are on a mac, then bashrc works fine, no need to continuously source ~/.profile for the terminal to read from the environment variables – Jose Mhlanga Jan 16, 2021 at 12:35

Note that this will not automatically update your path for the remainder of the session. To do this, you should run:

source ~/.profile 
source ~/.bashrc
                A couple of questions. 1) Shouldn't there be a colon between $PATH and /usr/bin.  2) Should /usr/bin even be there.  3) Shouldn't you rather use /usr/local/bin?
– Batandwa
                Jan 11, 2014 at 0:16
                Please note: it's often considered a security hole to leave a trailing colon at the end of your bash PATH because it makes it so that bash looks in the current directory if it can't find the executable it's looking for. Users who find this post looking for more information should be advised of this.
– erewok
                Jan 14, 2014 at 0:16
                @AdamRobertson It is unsafe- consider the scenario when you unpack a tarball, then cd to the directory you unpacked it in, then run ls---and then realize that the tarball had a malicious program called ls in it.
– Lily Chung
                Feb 27, 2014 at 0:39
                I think I significantly improved the quality of this answer, and addressed a few issues which other users brought up.  Every path export, or every command which adjusts the path, should always make sure to separate an existing path with a colon.  Leading or trailing colons should never be used, and the current directory should never be in the path.
– Erick Robertson
                Sep 4, 2014 at 17:43

There are multiple ways to do it. The actual solution depends on the purpose.

The variable values are usually stored in either a list of assignments or a shell script that is run at the start of the system or user session. In case of the shell script you must use a specific shell syntax and export or set commands.

System wide

  • /etc/environment List of unique assignments. Allows references. Perfect for adding system-wide directories like /usr/local/something/bin to PATH variable or defining JAVA_HOME. Used by PAM and systemd.

  • /etc/environment.d/*.conf List of unique assignments. Allows references. Perfect for adding system-wide directories like /usr/local/something/bin to PATH variable or defining JAVA_HOME. The configuration can be split into multiple files, usually one per each tool (Java, Go, and Node.js). Used by systemd that by design do not pass those values to user login shells.

  • /etc/xprofile Shell script executed while starting X Window System session. This is run for every user that logs into X Window System. It is a good choice for PATH entries that are valid for every user like /usr/local/something/bin. The file is included by other script so use POSIX shell syntax not the syntax of your user shell.

  • /etc/profile and /etc/profile.d/* Shell script. This is a good choice for shell-only systems. Those files are read only by shells in login mode.

  • /etc/<shell>.<shell>rc. Shell script. This is a poor choice because it is single shell specific. Used in non-login mode.

    User session

  • ~/.pam_environment. List of unique assignments, no references allowed. Loaded by PAM at the start of every user session irrelevant if it is an X Window System session or shell. You cannot reference other variables including HOME or PATH so it has limited use. Used by PAM.

  • ~/.xprofile Shell script. This is executed when the user logs into X Window System system. The variables defined here are visible to every X application. Perfect choice for extending PATH with values such as ~/bin or ~/go/bin or defining user specific GOPATH or NPM_HOME. The file is included by other script so use POSIX shell syntax not the syntax of your user shell. Your graphical text editor or IDE started by shortcut will see those values.

  • ~/.profile, ~/.<shell>_profile, ~/.<shell>_login Shell script. It will be visible only for programs started from terminal or terminal emulator. It is a good choice for shell-only systems. Used by shells in login mode.

  • ~/.<shell>rc. Shell script. This is a poor choice because it is single shell specific. Used by shells in non-login mode.

    Notes

    GNOME on Wayland starts a user login shell to get the environment. It effectively uses the login shell configurations ~/.profile, ~/.<shell>_profile, ~/.<shell>_login files.

    Man pages

  • environment
  • environment.d https://linux.die.net/man/1/environment.d
  • Distribution-specific documentation

  • Ubuntu
  • Arch Linux
  • Difference between Login Shell and Non-Login Shell?

    Thank you for the detailed answer, this should be higher up. Maybe .bash_profile should be added to the list as well? – James Ko Nov 11, 2016 at 23:12 I think the best answer is suggested /etc/environment. But can I refresh it without logging out and in? Sometimes I don't use bash or sh so source /etc/environment doesn't work. – banan3'14 Apr 8, 2018 at 20:22 My reason to search for this topic was actually Go. Glad to see I'm not the only one who realised that .bashrc is not the right place. ;) – Peter Gloor Jun 13, 2018 at 18:34

    In Ubuntu, edit /etc/environment. Its sole purpose is to store environment variables. Originally the $PATH variable is defined here.

    This is a paste from my /etc/environment file:

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

    So you can just open up this file as root and add whatever you want.

    For immediate results,

    Run (try as normal user and root):

    source /etc/environment && export PATH
    

    If you use Z shell (zsh), add this line right after the comments in /etc/zsh/zshenv file:

    source /etc/environment
    

    I encountered this little quirk on Ubuntu 15.10 (Wily Werewolf), but if your zsh is not getting the correct PATH, this could be why.

    @e-sushi I am actually shocked at that. I'm on ubuntu 14.04.1 myself. and I can promise you the file came built in. – trve.fahad Feb 28, 2015 at 12:18 After trying every suggestion under the sun but /etc/environment, and having them all NOT work, i finally stumbled across this. I am also on Ubuntu 14.04 and this is the only one that actually changed the PATH variable after reboots. – Chockomonkey Mar 24, 2015 at 16:21

    For Bash, you can put the export declaration in ~/.bashrc. For example, my .bashrc contains this line:

    export PATH=/var/lib/gems/1.8/bin:/home/ash/.bin:$PATH
                    It might be dependent on the exact system; I'm not sure exactly what conditions determine which file is executed. Glad the problem was solved, though.
    – ashastral
                    Feb 1, 2013 at 2:10
                    @Click Upvote You need to do source ~/.bashrc to to reload .bashrc configuration. Then it will work
    – BigSack
                    Apr 6, 2014 at 6:02
                    The export keyword is only needed if PATH is not already flagged as an environment variable -- which it almost unconditionally will be. Simply PATH=/var/lib/gems/1.8/bin:/home/fraxtil/.bin:$PATH would have the same effect.
    – Charles Duffy
                    Oct 4, 2014 at 17:20
    
  • To set the path for a particular user:

    You may need to make the entry in file .bash_profile in the home directory for the user.

    E.g, in my case I will set the java path in the Tomcat user profile*

     echo "export PATH=$PATH:/path/to/dir" >> /home/tomcat/.bash_profile
    
  • To set a common path for all system users, you may need to set the path like this:

     echo "export PATH=$PATH:/path/to/dir" >> /etc/profile
                    Is the file named /etc/profiles with an s on your distro?  Mine has no s.  I think you have a typo.
    – Chris Johnson
                    Oct 16, 2014 at 13:36
                    You probably want to escape the $ you are writing to the profile file. e.g. echo "export PATH=\$PATH:/path/to/dir" >> /etc/profile, that way you actually append to the variable when that script runs rather than setting it to a literal value based on it's value at the time of executing this initial command.
    – BuvinJ
                    Jan 20, 2016 at 15:12
                    echo "export PATH=$PATH:/path/to/dir" >> /home/<USERNAME>/.bashrc this worked for WSL with Kali distrubution. A new thing got that you can set any variable like echo "export PYTHONPATH=/path/to/dir" >> /home/<USERNAME>/.bashrc for new creation and echo "export PYTHONPATH=$PYTHONPATH:/path/to/dir" >> /home/<USERNAME>/.bashrc this for update.
    – Akash Shendage
                    Jun 8, 2022 at 11:20
    

    You can use on CentOS or Red Hat Linux (RHEL) for the local user:

    echo $"export PATH=\$PATH:$(pwd)" >> ~/.bash_profile
    

    This adds the current directory (or you can use another directory) to the PATH. This makes it permanent, but it takes effect at the next user logon.

    If you don't want do a re-logon, then you can use:

    source ~/.bash_profile
    

    That reloads the # User specific environment and startup programs. This comment is present in file .bash_profile.

    You can also set it permanently, editing one of these files:

    /etc/profile (for all users)

    ~/.bash_profile (for current user)

    ~/.bash_login (for current user)

    ~/.profile (for current user)

    You can also use /etc/environment to set a permanent PATH environment variable, but it does not support variable expansion.

    Extracted from: Linux: Añadir ruta al PATH

    vi /etc/profile
    

    Press the I key to enter editing mode and move the cursor to the end of the file. Additional entries:

    export PATH=$PATH:/path/to/dir;
    

    Press the Esc key to exit edit mode, and :wq to save the file.

  • Make the configuration effective

    source /etc/profile
    

    Explanation:

    The profile file works for all users. If you want it to be valid only for the active user, change the ".bashrc" file.

    I stumbled across this question yesterday when searching for a way to add a folder containing my own scripts to the PATH - and was surprised to find out that my own ~/.profile file (on Linux Mint 18.1) already contained this:

    # set PATH so it includes user's private bin if it exists
    if [ -d "$HOME/bin" ] ; then
        PATH="$HOME/bin:$PATH"
    

    Thus, all I had to do was create the folder ~/bin and put my scripts there.

    Also on Ubuntu MATE 20.04 (Focal Fossa). Standard for all Debian-based distributions? Or even wider than that? – Peter Mortensen Jul 25, 2021 at 11:47 oops, overlooked the question :( Well, the files + that bash considers their content, that's pretty much a bash built-in. So, if the snippet above is not there for you, yet, you can just easily add it. This looks good as a reference baeldung.com/linux/bashrc-vs-bash-profile-vs-profile And yes, it's there on Focal for me (gnome though):) – RobertG Oct 17, 2021 at 15:03 @ClickUpvote: What shell do you use? (And files that start with a dot are hidden, you need something like ls -a to see them.) – David Schwartz Feb 1, 2013 at 1:05 Incase you don't have any of those files (bashrc or profile) you can manually create them and they will automatically be used – trve.fahad Sep 7, 2014 at 1:20

    After so much research, I found a simple solution for this (I am using Elementary OS), inspired by Flutter – Step by Step Installation on Linux – Ubuntu.

    Run the following command to open the .bashrc file in edit mode. (You may also use vi or any other editor).

    ~$ sudo nano ~/.bashrc
    

    Add the following line at the end of the file and save.

    export PATH="[FLUTTER_SDK_PATH]/flutter/bin:$PATH"
    

    For example:

    export PATH="/home/rageshl/dev/flutter/bin:$PATH"
    

    I believe this is the permanent solution for setting the path in Flutter in a Ubuntu distribution.

    It can be directly added by using the following command:

    echo 'export PATH=$PATH:/new/directory' >> ~/.zshrc
    source ~/.zshrc
                    This is a valid answer -> the title only mentions Linux, so bash and ALSO zsh will do ... if the tagging is only "bash" we need to add "zsh" to the tags too
    – Carlos Saltos
                    Feb 2, 2018 at 15:04
    

    One way to add a permanent path, which worked for me, is:

    cd /etc/profile.d
    touch custom.sh
    vi custom.sh 
    export PATH=$PATH:/path according to your setting/
    

    Restart your computer and here we go; the path will be there permanently.

    You don't actually need to restart your computer. Logging out and back in again is sufficient. This is quite an elegant solution as it is very easy to backout any changes without needing to edit files. It is also easy to specify an if statement so that if a directory doesn't exist on the system, it isn't added to the PATH variable. – Warwick Dec 18, 2019 at 21:42 You need to use sudo to edit system files. You mustn't use Bash-only syntax in these files, which are shared with non-Bash shells. You can probably just remove the export as presumably your existing configuration already takes care of exporting this variable. If not, add export PATH on a separate line instead. – tripleee Aug 1, 2020 at 13:18 Also, /etc/profile.d is platform-specific; if this directory doesn't exist, check /etc/profile and see if it has options to source (aka .) files which are not managed by your OS so you don't have to edit this system file directly. – tripleee Aug 1, 2020 at 13:21

    Add script file [name_of_script].sh to the /etc/profile.d folder with the line:

    export PATH=$PATH:/dir
    

    Every script within the /etc/profile.d folder is automatically executed by /etc/profile on login.

    This is only if you want the settings to be system-wide, which is probably not the most common use case. Most people want (or should want) the path to be set locally, because most users/roles are doing contextually different operations, and the fewer assumptions you make, the better. – mpowered Apr 10, 2015 at 20:25 @mpowered, yeah, this is only for system-wide. If you want localy change PATH you should add the same export in ~/.profile or ~/.bashrc. Here you should consider that login shells read ~/.profile and interactive shells read ~/.bashrc. This is very important because ssh for example does not do an login, therefore ~/.profile will not be read. Several distibution like suse source ~/.bashrc in /etc/profile. But it's not common for all linux' – Yuriy Vasylenko Apr 15, 2015 at 9:49 If you are referencing executable scripts/apps, don't forget to source [name_of_script].sh to make these apps instantly available in the current shell – ObiHill Nov 18, 2020 at 14:12

    My answer is in reference to the setting up of a Go environment on Ubuntu Linux (amd64). I have faced the same trouble of setting the path of environment variables (GOPATH and GOBIN), losing it on terminal exit and rebuilding it using the source <file_name> every time.

    The mistake was to put the path (GOPATH and GOBIN) in ~/.bash_profile file. After wasting a few good hours, I found that the solution was to put GOPATH and GOBIN in the ~/.bash_rc file in the manner:

    export GOPATH=$HOME/go
    export GOBIN=$GOPATH/bin
    export PATH=$PATH:$GOPATH:$GOBIN
    

    And in doing so, the Go installation worked fine and there were no path losses.

    The reason with which this issue can be related is that settings for non-login shells, like your Ubuntu terminal or GNOME terminal where we run the Go code, are taken from the ~./bash_rc file and the settings for login shells are taken from ~/.bash_profile file. And from the ~/.profile file if the ~/.bash_profile file is unreachable.

    The files where you add the export command depends on if you are in login-mode or non-login-mode.

    If you are in login-mode, the files you are looking for are either /etc/bash or /etc/bash.bashrc.

    If you are in non-login-mode, you are looking for the file /.profile or for the files within the directory /.profiles.d

    The files mentioned above is where the system variables are.

    Permanently add to the PATH variable

    Global:

    echo "export PATH=$PATH:/new/path/variable" >> /etc/profile
    

    Local (for the current user only):

    echo "export PATH=$PATH:/new/path/variable" >> ~/.profile
    

    For global, restart. For local, relogin.

    Example

    Before:

    $ cat /etc/profile
    #!/bin/sh
    export PATH=/usr/bin:/usr/sbin:/bin:/sbin
    

    After:

    $ cat /etc/profile
    #!/bin/sh
    export PATH=/usr/bin:/usr/sbin:/bin:/sbin
    export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/new/path/variable
    

    Alternatively you can just edit file "profile":

    $ cat /etc/profile
    #!/bin/sh
    export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/new/path/variable
    

    Another way (thanks gniourf_gniourf):

    echo 'PATH=$PATH:/new/path/variable' >> /etc/profile
    

    You shouldn't use double quotes here! echo 'export PATH=$PATH:/new/path/variable'... And by the way, the export keyword is very likely useless as the PATH variable is very likely already marked as exported. – gniourf_gniourf

    Nope. You shouldn't use double quotes here! echo 'export PATH=$PATH:/new/path/variable'... And by the way, the export keyword is very likely useless as the PATH variable is very likely already marked as exported. – gniourf_gniourf Nov 14, 2014 at 17:48 Nope, you should use double quotes because $PATH in single quotes not interpolated. And BTW export also useful. – user3439968 Nov 14, 2014 at 17:58 I got it. You can use double quotes or use single quotes, because $PATH interpolated when the echo executed or interpolate when /etc/profile execute. – user3439968 Nov 14, 2014 at 18:14 @user3439968 actually, Double quotes will cause a lot of issues if you were to append to $PATH from multiple files. Consider: when you use double quotes, $PATH gets translated to a static string with all the previously defined PATH directories. say you append /usr/local to it using ~/.bashrc. now if you intend to append /opt/bin to the same variable using /etc/bash.bashrc; $PATH will translate to the same static string, as a result $PATH will be replaced instead of appended to... It will be a matter of system's preference to one file over another – trve.fahad Jan 27, 2015 at 16:20

    Zues77 has the right idea. The OP didn't say "How can I hack my way through this?". The OP wanted to know how to permanently append to $PATH:

    sudo nano /etc/profile
    

    This is where it is set for everything and is the best place to change it for all things needing $PATH.

    Let's say you're running macOS. You have a binary you trust and would like to make available across your system, but don't necessarily want the directory in which the binary is to be added to your PATH.

    You can opt to copy/move the binary to /usr/local/bin, which should already be in your PATH. This will make the binary executable like any other binary you may already have access to in your terminal.

    This is a one-liner. It adds a line to the .bashrc. That line is going to check if the directory has already been added to the path and append if not. This will prevent duplicating your directory in the path every time you source .bashrc.

    echo "[[ \":\$PATH:\" != *\":$(pwd)/path/to/add:\"* ]] && export PATH=\"\${PATH:+\${PATH}}:$(pwd)/path/to/add\"" >> ~/.bashrc
    source ~/.bashrc
                    If you single-quote the whole thing, you don't have to backslash-escape all the embedded double quotes.
    – tripleee
                    Aug 1, 2020 at 13:23
                    If you are on a mac, then bashrc works fine, no need to continuously source ~/.profile for the terminal to read from the environment variables
    – Jose Mhlanga
                    Jan 16, 2021 at 12:34
                    Yes, restarting does seem to be required. But what is the reason? Isn't there another way?
    – Peter Mortensen
                    Jul 25, 2021 at 12:31
                    The simple fix is to log out and back in. A common alternative solution is source .bashrc but it will re-execute everything in there, so you might end up with some things doubled or etc. Some users take care to make their .bashrc idempotent (check if something was already done and don't do it again if that could have undesired consequences) but that makes it more complicated. Of course, if you know what you are doing, just manually make whatever changes are necessary in the currently running shell.
    – tripleee
                    Feb 27 at 15:48
    
  •