I need to add a path in a bash script, but it may be executed several times:

export PATH=${OPENSHIFT_HOMEDIR}/app-root/runtime/bin/:${PATH}

I don't want that path to be added over and over. How can I add it if it is not in $PATH yet?


First check if the path to add is already part of the variable:

[[ ":$PATH:" != *":/path/to/add:"* ]] && PATH="/path/to/add:${PATH}"

If /path/to/add is already in the $PATH, then nothing happens, else it is added at the beginning.

If you need it at the end use PATH=${PATH}:/path/to/add instead.

Edit: In you case it would look like this:

[[ ":$PATH:" != *":${OPENSHIFT_HOMEDIR}/app-root/runtime/bin:"* ]] && PATH="${OPENSHIFT_HOMEDIR}/app-root/runtime/bin:${PATH}"
  • Can I write it like this? [[ ":$PATH:" != "${OPENSHIFT_HOMEDIR}/app-root/runtime/bin/" ]] && PATH="${OPENSHIFT_HOMEDIR}/app-root/runtime/bin/:${PATH}" ? Sorry, I am no expert with unix scripting... – Jérôme Verstrynge Jul 22 '15 at 13:28
  • @JVerstry See my edited answer – chaos Jul 22 '15 at 13:30
  • The colons before and after on both sides of the equals are for when adding a prefix of something already in PATH, e.g. adding '/home' when '/home/chaos/bin' is already present. Otherwise, the comparison would incorrectly say that '/home' was already present. – TamaMcGlinn Jan 7 at 13:42

The sysadmin in my old lab had a nifty little function for this:

pathmunge () {
        if ! echo "$PATH" | /bin/grep -Eq "(^|:)$1($|:)" ; then
           if [ "$2" = "after" ] ; then

It will both check whether the string given is already in the PATH and also lets you add it to the end or the beginning as desired:

$ echo $PATH
$ pathmunge /sbin/             ## Add to the start; default
$ echo $PATH
$ pathmunge /usr/sbin/ after   ## Add to the end
$ echo $PATH

I have this function in my ~/.profile and use it to modify my $PATH.

  • Wonder who's the original author of this particular function. It's kinda ubiquitous. – Deer Hunter Jul 22 '15 at 19:19
  • @DeerHunter yeah, I've seen it around. All I know is that it's not mine and that my ex sysadmin gave it to me. Whether or not it's his is another matter :). It's pretty straightforward though, I'm sure many people have written this or a very similar approach independently. – terdon Jul 22 '15 at 23:47
  • 4
    if using bash (v3.0 or later) may be cleaner to if [[ "${X}" =~ (^|:)${1}($|:) ]] ; ... – nhed Nov 13 '17 at 21:09

If it's the same string, then just do it:

set -a -- "$OPENSHIFT_HOMEDIR/app-root/runtime/bin/"
set +a --

You can do that over and over and the value of $PATH won't change.

Alternatively you can check for it.

set -a -- "$OPENSHIFT_HOMEDIR/app-root/runtime/bin/"
case :${PATH:=$1}: in
(*:"$1":*) ;; (*)
esac;  set +a --

With GNU sed you can do it by

echo ${PATH} | 
    sed "\|${OPENSHIFT_HOMEDIR}/app-root/runtime/bin|\
        ! s|^|export PATH=${OPENSHIFT_HOMEDIR}/app-root/runtime/bin:|e"

Not the answer you're looking for? Browse other questions tagged or ask your own question.