I'm using zsh terminal, and I'm trying to add a new entry (/home/david/pear/bin
) to the PATH
variable. I don't see a reference to the PATH
variable in my ~/.zshrc
file, but doing echo $PATH
returns:
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
So I know that the path variable is being set somewhere. Where is the PATH
variable set / modified for the zsh terminal?
.zshenv
, not in .zshrc
...
Actually, using ZSH allows you to use special mapping of environment variables. So you can simply do:
# append
path+=('/home/david/pear/bin')
# or prepend
path=('/home/david/pear/bin' $path)
# export to sub-processes (make it inherited by child processes)
export PATH
For me that's a very neat feature which can be propagated to other variables. Example:
typeset -T LD_LIBRARY_PATH ld_library_path :
Here, add this line to .zshrc
:
export PATH=/home/david/pear/bin:$PATH
EDIT: This does work, but ony's answer above is better, as it takes advantage of the structured interface ZSH provides for variables like $PATH
. This approach is standard for bash
, but as far as I know, there is no reason to use it when ZSH provides better alternatives.
PATH="/home/david/pear/bin:/usr/bin:etc"
to PATH=/home/david/pear/bin:/usr/bin:etc
for it to stay in zshrc.
PATH
from the parent process that started it, and then when it runs .zshrc
(or .bashrc
or whatever), that's what lets you add extra things to that path.
You can append to your PATH
in a minimal fashion. No need for parentheses unless you're appending more than one element. It also usually doesn't need quotes. So the simple, short way to append is:
path+=/some/new/bin/dir
This lower-case syntax is using path
as an array, yet also affects its upper-case partner equivalent, PATH
(to which it is "bound" via typeset
).
(Notice that no :
is needed/wanted as a separator.)
Common interactive usage
Then the common pattern for testing a new script/executable becomes:
path+=$PWD/.
# or
path+=$PWD/bin
Common config usage
You can sprinkle path settings around your .zshrc
(as above) and it will naturally lead to the earlier listed settings taking precedence (though you may occasionally still want to use the "prepend" form path=(/some/new/bin/dir $path)
).
Related tidbits
Treating path
this way (as an array) also means: no need to do a rehash
to get the newly pathed commands to be found.
Also take a look at vared path
as a dynamic way to edit path
(and other things).
You may only be interested in path
for this question, but since we're talking about exports and arrays, note that arrays generally cannot be exported.
You can even prevent PATH
from taking on duplicate entries (refer to this and this):
typeset -U path
PATH pre-populated
The reason your path already has some entries in it is due to your system shell files setting path for you. This is covered in a couple other posts:
Why and where the $PATH env variable is set?
Where is the source of $PATH? I cannot find it in .zshrc
path+='my/path' # for fun
. It’s obvious if you have spaces, but not so much if you have comments.
path
. A preceding :
is required for PATH
, as follows in .zshrc PATH+=:/Users/path/to/my/folder
typeset -aU path
one liner, without opening ~/.zshrc
file
echo -n 'export PATH=~/bin:$PATH' >> ~/.zshrc
or
echo -n 'export PATH=$HOME/bin:$PATH' >> ~/.zshrc
To see the effect, do source ~/.zshrc
in the same tab or open a new tab
Added path to ~/.zshrc sudo vi ~/.zshrc add new path export PATH="$PATH:[NEW_DIRECTORY]/bin" Update ~/.zshrc Save ~/.zshrc source ~/.zshrc Check PATH echo $PATH
Bash
way.
OPTION 1: Add this line to ~/.zshrc:
export "PATH=$HOME/pear/bin:$PATH"
After that you need to run source ~/.zshrc
in order your changes to take affect OR close this window and open a new one
OPTION 2: execute it inside the terminal console to add this path only to the current terminal window session. When you close the window/session, it will be lost.
for me PATH=$PATH:/path/to/file/bin
then export PATH
worked. to check echo $PATH
. other solutions are adding the path temporarily.
to verify your new directory has been added correctly, you can use
print -l $path
thanks to the fact that its type is known to be an array
If you are on macOS (I'm on Monterey 12.3.1), you may have been pulling your hair like I did metaphorically. These instructions above all worked for me within the terminal session, but I could never get it to persist no matter what I did with export. Moreover, I couldn't find the .zshrc anywhere.
Turns out Apple does it differently. The file you need to edit is etc/paths
. You can simply sudo nano /etc/paths
and add your path in a new line. Then simply restart terminal and voila.
I'm on Monterey 12.4 and the only way I could change the path was using the helper function. Editing text files in nano did diddly squat
# append
path+=('/foo/bar/yourpath')
# export to sub-processes
export PATH
Success story sharing
~/.zshrc
is sourced after.profile
, and overwrites everything in.profile
. Took a while pulling my hair to figure it out.-x
and leave only unique values in a variable with-U
, colon is assumed by default, so it can be:typeset -TUx PATH path
path=(...)
(without referencing$path
or$PATH
inside) assigns,path=(... $path)
prepends andpath+(...)
appends.