Setting PATH vs. exporting PATH in ~/.bash_profile
What’s the difference and which is better to use when customizing my bash profile? Documentation on the export
command is scarce, as it’s a builtin cmd.
Excerpt from version 1 of my ~/.bash_profile:
#PATH export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:$HOME/bin #add Homebrew’s sbin to PATH export PATH=/usr/local/sbin:$PATH
Output from:
echo $PATH
/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/njboot/bin
Excerpt from version 2:
#PATH PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:$HOME/bin #add Homebrew’s sbin to PATH export PATH=/usr/local/sbin:$PATH
Output from
echo $PATH
is the same as in version 1. env
is the same as well.So:
- 1) What’s the benefit of using
export
vs. setting PATH explicitly? - 2) Is there any functional difference between version 1 and version 2 when applied?
- 3) Which should I use and why?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
To answer your questions specifically:
-
export
does set the$PATH
explicitly. -
No.
export
sets environment for child processes, but$PATH
is already set for the current environment. So, in the second example, when the command is read-in – and beforeexport
is executed – the current environment’s value for$PATH
is expanded into the$PATH
word. - You should use whichever is necessary and/or comfortable for you. Neither makes any difference functionally, so this is primarily a question of style.
POSIX defines the export
builtin so:
The shell shall give the
export
attribute to the variables corresponding to the specified names, which shall cause them to be in the environment of subsequently executed commands. If the name of a variable is followed by = word, then the value of that variable shall be set to word.
From another of my answers:
There is little difference between declaring a shell variable and an environment variable. Because export is a builtin it declares an environment variable for the process next invoked, but if you don’t invoke one that process remains the shell, and so your variable is twice evaluated.
You can remove all exports without any effect at all on exported variables so long as you don’t use export
to twice evaluate. By twice evaluate I mean:
var1=var2 export "${var1}=var3" echo "$var2" var3
Instead just use:
set -a
…at the top of the script. All variables defined thereafter will be automatically
exported
– which would include variables you might not have previously export
ed. Alternatively you could only set -a
for a portion of the script and later set +a
to unset it – it could also work as function.But subshells automatically inherit variable values anyway, so:
var1=value ( echo "$(echo "$var1")" ) value
export
makes no difference in that case.But if your script calls another script, or any other executable that interprets values you’ve export
ed and you cease to export
them, then those values will no longer be available in their environment. In the following example I use the shell variable $PS1
– which defines the contents of an interactive shell’s prompt – to demonstrate how variations on export
ed variables affect child processes.
export PS1="$(printf "this is another executablen > ")" echo exit | sh -i ###OUTPUT### this is another executable > exit exit
But …
PS1="$(printf "this is another executablen > ")" echo exit | sh -i ###OUTPUT### sh-4.3$ exit exit
But then again, if you explicitly declare environment variables while invoking a process…
PS1="$(printf "this is another executablen > ")" { echo exit | PS1=$PS1 sh -i echo exit | sh -i } ###OUTPUT### this is another executable > exit exit sh-4.3$ exit exit
Any of the
ENV
files first invoked by a shell such as .bashrc
or .profile
will set variable values for the life of that shell. So any variables that are set and export
ed within those files will maintain that export
characteristic and be export
ed to all child processes invoked by that shell for the life of the shell or until they are unset
.It is notable, though, that bash
extends the export
builtin somewhat to include the -n
option – which enables you to remove the export
attribute from a variable without unset
ting it, but this is not portable behavior.
Method 2
A short answer:
https://superuser.com/a/153378/333431
Exported variables get passed on to child processes, not-exported
variables do not.
This means you should export
your variables, if you intend to use them in subshells.
You can test this:
$ TEST="im_not_here" $ echo $TEST im_not_here $ bash -c 'echo $TEST' <empty output> $ export TEST2="im_here" $ echo $TEST2 im_here $ bash -c 'echo $TEST2' im_here
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0