Skip to content

Comment on How to add a directory to your PATH

Comments

FWIW in bash I have 2 functions:

  path_add() {
      export PATH=$PATH:$(string_join ':' $@)
  }

  path_prepend() {
      PATH=$(string_join ':' "$@"):$PATH
      export PATH
  }
These can join an arbitrary list of paths to PATH. e.g.
  path_add /usr/bin /usr/local/bin ~/bin
They depend on another one:
  string_join() {
      local join=$1; shift
      local result=$1; shift
      for p in "$@"; do
        result="${result}${join}${p}"
      done
      echo -n "$result"
      set +x
  }
I also have ones for adding and prepending to LD_LIBRARY_PATH

The compact one-liners below are similar but avoid adding duplicate items to PATH, so are fine to call in various init scripts.

In Bash:

  path_append() { local p; for p; do [[ :"$PATH": =~ :"$p": ]] || PATH+=:$p; done; }
  path_prepend() { local p; for p; do [[ :"$PATH": =~ :"$p": ]] || PATH=$p:$PATH; done; }
In portable POSIX shell:
  path_append() { for p; do case :"$PATH": in *:"$p":*) ;; *) export PATH="$PATH:$p" ;; esac; done; }
  path_prepend() { for p; do case :"$PATH": in *:"$p":*) ;; *) export PATH="$p:$PATH" ;; esac; done; }

I cribbed these from someplace - slightly different approach:

  ###################################################################
  # Add directory to path
  pathadd() {          
      newelement=${1%/}
      if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then
          if [ "$2" = "after" ] ; then
              PATH="$PATH:$newelement"
          else         
              PATH="$newelement:$PATH"
          fi
      fi
  }
 
  ###################################################################
  # Remove directory from path
  pathrm() {
      PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|\$\);\1\2;g" -e \
      's;^:\|:$;;g' -e 's;::;:;g')"
  }

Do any of these guard against an empty value on either side ?

"export PATH=$DIR:$PATH - That particular pattern is way too common, and is very dangerous if you consider the case when [$DIR or] $PATH (or whatever your variable is, like $LD_LIBRARY_PATH) isn’t set. Then, the value will be :/path/to/dir, which usually means both /path/to/dir and the current directory, which is usually both unexpected behaviour and a security concern."

I'm surprised both the blog post and all the other comments don't mention how it should have logic to check if the item exists in the path before adding it. Otherwise you get duplicates added everytime you source your config.

Your function does that so +1. Though I'd use

    [[ $PATH =~ "(^|:)$newelement($|:)" ]] 
over grep -q but it functions the same.

Another option is to set the full $PATH value explicitly instead of doing an add thing for each directory. This avoids duplicates and the extra logic, but maybe isn't as convenient.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.