Adding a new entry to the PATH variable in ZSH
Solution 1
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.
Solution 2
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 :
Solution 3
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
Solution 4
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
Solution 5
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
David Barreto
I'm an Electronic Engineer by proffesion but a Software Developer by passion. I was born in Maracaibo (Venezuela) but I'm currently living in Toronto (Canada). I've worked with many different languages (HTML, CSS, Javascript, PHP, MySQL, MongoDB) and frameworks (Symfony2, JQuery, JQuery UI, Mootools, Twitter Bootstrap, AngularJS, Angular2) and I feel as confortable working in the front as in the backend of an application.
Updated on February 05, 2022Comments
-
David Barreto about 2 years
I'm using zsh and I'm trying to add a new entry (
/home/david/pear/bin
) to thePATH
variable but I don't know how.The thing that confuses me the most is that there's not a single reference to a
PATH
variable in my~/.zshrc
file, but doingecho $PATH
returns:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
So a
PATH
variable is being set somewhere. -
David Barreto almost 12 yearshaha forget it, I though that was only a console command but adding that line to the .zshrc did the trick. Thanks a lot!
-
Zack Huston about 10 yearsMy .zshrc already had a line for export PATH so I replaced it with the modified one.
-
Khanh Nguyen almost 10 yearsNice answer. In my case,
~/.zshrc
is sourced after.profile
, and overwrites everything in.profile
. Took a while pulling my hair to figure it out. -
a7omiton about 9 yearsI had to remove the double quotes around the entries i.e.
PATH="/home/david/pear/bin:/usr/bin:etc"
toPATH=/home/david/pear/bin:/usr/bin:etc
for it to stay in zshrc. -
Micah Elliott almost 9 yearsThe append case does does not need the parens unless you're appending more than one element. It also often doesn't need the quotes. So the simple, short way to append is
-
mencargo over 8 years@taco, you can use $HOME
-
ony about 8 years@SuperUberDuper, you should understand that almost any unix shell simply reads startup files which does almost the same as if you'd type it into shell interactively. Regarding "rc" files you might find interesting answer to this question
-
sstruct over 7 yearsIt will erase all the old PATH, try
export PATH=$PATH:/path/to/dir
-
Grief about 7 yearsIt's possible to avoid explicit export with
-x
and leave only unique values in a variable with-U
, colon is assumed by default, so it can be:typeset -TUx PATH path
-
andrew lorien over 6 yearsShould it not be 'path+=:/foo/bar'? (with a colon)
-
Micah Elliott over 6 years@andrewlorien I updated the answer with details about the colon separator.
-
Stryker about 6 yearsWorked perfecly on OSX with Zsh shell.
-
Franklin Yu about 5 yearsNote that if there’s a comment after the path, then we do need quotes, like
path+='my/path' # for fun
. It’s obvious if you have spaces, but not so much if you have comments. -
Franklin Yu about 5 yearsCan you elaborate on how this answer is different from the same answer posted 5 years ago?
-
Dimitar about 5 yearsin this answer it is not said that you have to add this line of code to the file, if you just run it like that it will change only in the current windows and this is not explain in the original answer
-
Akbarsha about 5 yearsWorked like a charm!
-
CousinCocaine over 4 yearsI see the use of
path
andPATH
, both are separate entities? -
CousinCocaine over 4 yearsThis is the
Bash
way. -
ony over 4 years@CousinCocaine, you are right. ZSH variables are case-sensitive.
typeset -T
allows to tiePATH
andpath
together in a special way that internally ZSH manages array variablepath
and reflects its contents inPATH
as a scalar. -
Dani over 4 yearsThis appends to my existing PATH, and every time it's run, appends again. How do I set exactly what PATH should be?
-
Dani over 4 yearsHow do I set exactly what PATH should be, as opposed to appending to it? Because every time
.zshrc
is executed, PATH gets whatever is declared in.zshrc
appended to it again and again. -
Linuxios over 4 yearsYou can set
PATH
directly @DanielSpringer:export PATH=/some/where:/bin:/usr/bin
and so on. Is that what you're asking? The idea is to run the code in this answer in the.zshrc
or.profile
or something like that at the beginning of each session. -
Linuxios over 4 years@DanielSpringer: Yes. When you open a shell it inherits
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. -
Linuxios over 4 years@DanielSpringer: Worth noting that you have to add the folder they're in to your path, not the path to the script file itself.
-
Dani over 4 years@Linuxios Ah, and do I need to add the path to the file itself too, or just its folder?
-
Linuxios over 4 yearsJust the folder.
PATH
is a list of places (folders; directories) where the shell will look for commands you try to run. For example, when you runwget ...
the shell is looking for and finding thewget
binary in/usr/bin
, for example, which is in the defaultPATH
. -
ony over 4 years@DanielSpringer, there is a hint in second example. By just writing
path=(...)
you get it set. You might be interested as well in comment from @Grief about-U
. And I'd recommend modifyingPATH
environment from~/.*profile
-like files so they will not execute when you run inner shell. See also something like shreevatsa.wordpress.com/2008/03/30/… or other similar tips. -
Dani over 4 yearsIt seems that "path=" appends to path rather then setting it. What I didn't know is that path is reset upon relaunching Terminal/Shell/(maybe?)Login session
-
ony over 4 years@DanielSpringer, no. If you want it in those terms then:
path=(...)
(without referencing$path
or$PATH
inside) assigns,path=(... $path)
prepends andpath+(...)
appends. -
caram over 4 yearsYou can even have it as 1-liner:
export path=(... $path)
. -
Randy almost 4 yearsThis doesn't work for me on my mac. I use the one liner answer below that updates ~/.zshrc insead.
-
Emmett R. almost 4 years"(Notice that no : is needed/wanted as a separator.)" This is only true for a lowercase
path
. A preceding:
is required forPATH
, as follows in .zshrcPATH+=:/Users/path/to/my/folder
-
Timo over 3 yearsI use a lot
exec zsh
because I work with plugins fromoh-my-zsh
.Everytime I do exec the path gets bigger. Should I "default" the path from time to time? -
Milan Tarami over 3 yearseffective way to do
-
Timo over 3 years@KhanhNguyen how can I see when these files are sourced? Is there a cmd?
-
ony over 3 years@Timo, in case of zsh you can try something like
zsh -x -i -l -c true
to see all commands during shell start-up. That-l
is to simulate login-like start (as it happens from text VT or overssh
). But you should understand that not alwayszsh
will be started as login (e.g. graphical session) and some other parent process may somehow source.profile
before spawning non-loginzsh
sub-process that inherits environment variables (includingPATH
) from parent process. -
Rotkiv over 3 yearsWhat if i want to use $HOME inside ' '? path +=('$HOME/etc/etc') doesn't seem to work
-
ony about 3 years@Rotkiv, that's a bit different question about how single/double quotes are interpreted. I guess zsh expansion covers this. Usually double-quotes allow string interpolation like
"$HOME/etc/etc"
, but single quotes makes it easier to represent text that should not get special treatment. Note that you can always mix in a single argument forms to have something like"$HOME"'/etc/etc'
(double + single quotes) or"$HOME"/etc/etc
(double quotes + unquoted). P.S. Yes I'm lazy to try find link to good answer on SO :P -
Jost about 3 yearsOn macOS, you can prepend and append to your path variable as described in the post, adding to the .zshrc file. It works without exporting the PATH.
-
Hamza Waleed almost 3 yearsJust a side note, if your path has a space in it. then you need to wrap your path in double quotes like this:
export PATH=$PATH:"/Applications/Android Studio.app/Contents"
-
Yerke almost 3 yearsIf this append or prepend syntax doesn't work for you, make sure that you are using lower case
path
. Lower casepath
is the array. -
C. Sederqvist almost 3 yearsFor ZSH to interpret $PATH as an array and make it unique, I believe the correct way would be
typeset -aU path
-
MEMark over 2 yearsThank you for showing the prepend as well! Didn't see it anywhere else.
-
Minh Nghĩa over 2 yearsThis does not seem to work with
~
. -
Phil over 2 yearsThis didn't work for me even though things looked absolutely fine when I
echo $PATH
. I had to go back to the "traditional" syntax of something like:export PATH=$ANDROID_HOME/platform-tools:$PATH
-
ony over 2 years@MinhNghĩa,
~
is expanded by shell. If you put it in quotes like'~/bin'
or"~/bin"
it will be literally tilda in your path. E.g. you can writepath+=(~/bin)
(note no quotes) or similar. If you need to quote something, you still can do it on part likepath+=(~/'some path with spaces')
. -
ony over 2 years@Phil, my best guess for your case is that ok result of
echo $PATH
shows your current shell value for it. Any chance it works if you doexport PATH
(upper case) to export for sub-process after settingpath
(lower case)?