How to correctly add a path to PATH?
I’m wondering where a new path has to be added to the PATH environment variable. I know this can be accomplished by editing .bashrc (for example), but it’s not clear how to do this. This way:
If there are already some paths added, e.g. PATH=$PATH:$HOME/.local/bin:$HOME/bin , another can be added by separating with a : e.g. PATH=$PATH:$HOME/.local/bin:$HOME/bin:/home/ec2-user/pear/bin .
12 Answers 12
The simple stuff
depending on whether you want to add ~/opt/bin at the end (to be searched after all other directories, in case there is a program by the same name in multiple directories) or at the beginning (to be searched before all other directories).
You can add multiple entries at the same time. PATH=$PATH:~/opt/bin:~/opt/node/bin or variations on the ordering work just fine. Don’t put export at the beginning of the line as it has additional complications (see below under “Notes on shells other than bash”).
If your PATH gets built by many different components, you might end up with duplicate entries. See How to add home directory path to be discovered by Unix which command? and Remove duplicate $PATH entries with awk command to avoid adding duplicates or remove them.
Some distributions automatically put ~/bin in your PATH if it exists, by the way.
Where to put it
Put the line to modify PATH in ~/.profile , or in ~/.bash_profile or if that’s what you have. (If your login shell is zsh and not bash, put it in ~/.zprofile instead.)
The profile file is read by login shells, so it will only take effect the next time you log in. (Some systems configure terminals to read a login shell; in that case you can start a new terminal window, but the setting will take effect only for programs started via a terminal, and how to set PATH for all programs depends on the system.)
Note that ~/.bash_rc is not read by any program, and ~/.bashrc is the configuration file of interactive instances of bash. You should not define environment variables in ~/.bashrc . The right place to define environment variables such as PATH is ~/.profile (or ~/.bash_profile if you don’t care about shells other than bash). See What’s the difference between them and which one should I use?
Don’t put it in /etc/environment or ~/.pam_environment : these are not shell files, you can’t use substitutions like $PATH in there. In these files, you can only override a variable, not add to it.
Potential complications in some system scripts
You don’t need export if the variable is already in the environment: any change of the value of the variable is reflected in the environment.¹ PATH is pretty much always in the environment; all unix systems set it very early on (usually in the very first process, in fact).
At login time, you can rely on PATH being already in the environment, and already containing some system directories. If you’re writing a script that may be executed early while setting up some kind of virtual environment, you may need to ensure that PATH is non-empty and exported: if PATH is still unset, then something like PATH=$PATH:/some/directory would set PATH to :/some/directory , and the empty component at the beginning means the current directory (like .:/some/directory ).
if [ -z "$" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi
Notes on shells other than bash
In bash, ksh and zsh, export is special syntax, and both PATH=~/opt/bin:$PATH and export PATH=~/opt/bin:$PATH do the right thing even. In other Bourne/POSIX-style shells such as dash (which is /bin/sh on many systems), export is parsed as an ordinary command, which implies two differences:
- ~ is only parsed at the beginning of a word, except in assignments (see How to add home directory path to be discovered by Unix which command? for details);
- $PATH outside double quotes breaks if PATH contains whitespace or \[*? .
So in shells like dash, export PATH=~/opt/bin:$PATH sets PATH to the literal string ~/opt/bin/: followed by the value of PATH up to the first space. PATH=~/opt/bin:$PATH (a bare assignment) doesn’t require quotes and does the right thing. If you want to use export in a portable script, you need to write export PATH=»$HOME/opt/bin:$PATH» , or PATH=~/opt/bin:$PATH; export PATH (or PATH=$HOME/opt/bin:$PATH; export PATH for portability to even the Bourne shell that didn’t accept export var=value and didn’t do tilde expansion).
¹ This wasn’t true in Bourne shells (as in the actual Bourne shell, not modern POSIX-style shells), but you’re highly unlikely to encounter such old shells these days.
Add a bash script to path
I want to add a small script to the linux PATH so I don’t have to actually run it where it’s physically placed on disk. The script is quite simple is about giving apt-get access through a proxy I made it like this:
#!/bin/bash array=( $@ ) len=$ _args=$ sudo http_proxy="http://user:password@server:port" apt-get $_args
Then I saved this as apt-proxy.sh, set it to +x (chmod) and everything is working fine when I am in the directory where this file is placed. My question is : how to add this apt-proxy to PATH so I can actually call it as if it where the real apt-get ? [from anywhere] Looking for command line only solutions, if you know how to do by GUI its nice, but not what I am looking for.
Depending on your needs/options, either pointing PATH to the script (already detailed in answers) or moving the script to a location already available will both achieve the desired result. I usually drop a script in /usr/local/bin .
5 Answers 5
- Save the script as apt-proxy (without the .sh extension) in some directory, like ~/bin .
- Add ~/bin to your PATH , typing export PATH=$PATH:~/bin
- If you need it permanently, add that last line in your ~/.bashrc . If you’re using zsh , then add it to ~/.zshrc instead.
- Then you can just run apt-proxy with your arguments and it will run anywhere.
Note that if you export the PATH variable in a specific window it won’t update in other bash instances.
You don’t need to export PATH as it is (very likely) already marked as exported. Also, it might be better to prepend your personal paths, rather than to append them to existing PATH .
@compguy24: so that they are searched before. If you have an executable my_command in both dirA and in dirB , and your PATH is PATH=dirA:dirB then the one in dirA will be found first, and hence it’s dirA/my_command that will be run. Usually, the personal ones are meant to override the system-wide ones; that’s why it’s usually preferable to prepend your personal ones to PATH .
You want to define that directory to the path variable, not the actual binary e.g.
where MYDIR is defined as the directory containing your binary e.g.
You should put this in your startup script e.g. .bashrc such that it runs each time a shell process is invoked.
Note that order is important, and the PATH is evaluated such that if a script matching your name is found in an earlier entry in the path variable, then that’s the one you’ll execute. So you could name your script as apt-get and put it earlier in the path. I wouldn’t do that since it’s confusing. You may want to investigate shell aliases instead.
I note also that you say it works fine from your current directory. If by that you mean you have the current directory in your path ( . ) then that’s a potential security risk. Someone could put some trojan variant of a common utility (e.g. ls ) in a directory, then get you to cd to that directory and run it inadvertently.
Add a binary to my path
I have an executable. I want to execute the executable in terminal with name only like other commands. I can put my executable in /usr/local/bin or I could add its PATH to ~/.bashrc . Both will work. What is better? Is there any difference?
4 Answers 4
For example let me assume, you have an executable myscript . You need to run it from a terminal as,
User level Change
If you add the PATH of that executable to ~/.bashrc , you can run the executable with name only from anywhere (Avinash Raj already mentioned), as
But the change will be affected in user level. That means if you have any other user(s) they could not access the executable with name only. If they have proper permission they need to run the executable as,
Also, you will not be able to run the script as sudo as it is not in PATH of root, To run as sudo you need to use,
system level change
If you put your script in /usr/local/bin it can be accessed system wide and for all users. In that case any user can run your executable as (subject to having proper permissions)
In that case you can run the executable as sudo also as,
Now choose one way depending upon your need.
Adding the location of the file to your $PATH variable in your ~/.bashrc file will only allow you to execute from any location, whereas putting it in /usr/bin/ will allow all users on your system to execute that file from any location.
Why is that? Because, your ~/.bashrc file is only visible to you as a user. So all variable changes done are limited to you. Whereas, adding that file to /usr/bin will allow the file to remain there for all users and since /usr/bin is present in the $PATH variable unless someone removes it, will allow all users to execute it from any location.
If you put the executable file in /usr/bin or /usr/local/bin , then you will be able to run that program by only specifying the name ( your-program instead of /usr/local/bin/your-program ).
If you instead add the directory containing the program to the ~/.bashrc file to the PATH , then any executable file present in that directory can be launched by only typing its name.
This information is false, you can stil launch the executable even if you are not in «that directory».
Ok, I had a hard time reading your answer (and thereby made an error) so I edited it to remove the confusion and remoted the downvote. Hopefully it helps.
So, the question is: What is better? Is there any difference? You practically didn’t say nothing more than the OP.