A typical modification to the PATH in ~/.bash_profile looks something like this:
export PATH=$PATH:/usr/local/Cellar/node/14.2.0/bin
The problem is that if the file is "sourced" twice in the shell, your path ends up looking like this, with the same directory there twice. It works, but it slows things down:
$ source ~/.bash_profile
$ echo $PATH /usr/bin:/usr/local/Cellar/node/14.2.0/bin:/usr/local/Cellar/node/14.2.0/bin $
So don't source it then! Unfortunately sourcing has to happen in all kinds of situations, including:
- Something was added and the current shell needs the update
- A new shell at the command with -l or --login will source ~/.bash_profile over the existing environment
- ~/.bashrc is usually read in the original login shell, and then sourced again in each sub-shell which is over the existing environment
We have a simple fix, use a conditional statement to add something to PATH only if it is not already there:
dir=/usr/local/Cellar/node/14.2.0/bin
if echo $PATH | grep -v -q node then export PATH=$PATH:$dir fi
Notice that the check is not for the directory itself, what if the directory was changed. The check is to look for something that is unique to this directory in the PATH.
Unfortunately the fix only handles new PATH entries, not a change to existing values. We can fix that by using sed to replace what is there when something already exists:
Unfortunately the fix only handles new PATH entries, not a change to existing values. We can fix that by using sed to replace what is there when something already exists:
dir=/usr/local/Cellar/node/14.2.0/bin if echo $PATH | grep -v -q node then export PATH=$PATH:$dir else export PATH=$(echo $PATH | sed -E "s|(.*):?([^:]*node[^:]*):?(.*$)|\1:$DIR:\3|" | sed -E "s|::|:|g" | sed -E "s|:$||") fi
There are three sed commands in the pipeline; the second two strip out empty and trailing colons if they end up in the PATH.
None of this is absolutely perfect, for example if the unique word we are looking for changes and we need to replace the directory it really will not work. But, what we have done is really not complicated and covers most of the scenarios. It is just a matter of consistently using conditional statements in the shell startup files to avoid duplication in environment variables like PATH.
No comments:
Post a Comment