28

This question already has an answer here:

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?

marked as duplicate by Gilles bash Jul 22 '15 at 21:52

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

47

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
17

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
              PATH="$PATH:$1"
           else
              PATH="$1:$PATH"
           fi
        fi
}

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
/usr/local/bin:/usr/bin:/bin
$ pathmunge /sbin/             ## Add to the start; default
$ echo $PATH
/sbin/:/usr/local/bin:/usr/bin:/bin
$ pathmunge /usr/sbin/ after   ## Add to the end
$ echo $PATH
/sbin/:/usr/local/bin:/usr/bin:/bin:/usr/sbin/

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
  • 3
    if using bash (v3.0 or later) may be cleaner to if [[ "${X}" =~ (^|:)${1}($|:) ]] ; ... – nhed Nov 13 '17 at 21:09
2

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

set -a -- "$OPENSHIFT_HOMEDIR/app-root/runtime/bin/"
PATH=$1:${PATH#"$1:"}
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":*) ;; (*)
    PATH=$1:$PATH
esac;  set +a --
1

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.