From 6c7b29705e61a9adaef1cc1db0e5b704c71a956c Mon Sep 17 00:00:00 2001 From: Fernando Schauenburg Date: Thu, 3 Dec 2020 18:34:23 +0100 Subject: [PATCH] [bash] improve PATH manipulation The previous implementation failed to prevent duplicates if the entry being added was the only entry already present in the path. The reason is that it always required a : to be present in order to remove the new entry before adding it. The new implementation is clearer and solves that. However, if the new entry is already present it will be kept where it was, not moved to the front of the list. This is fine at the moment. --- roles/bash/files/profile | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/roles/bash/files/profile b/roles/bash/files/profile index 8f802e3..619cb62 100644 --- a/roles/bash/files/profile +++ b/roles/bash/files/profile @@ -39,17 +39,19 @@ export VIMINIT='let $MYVIMRC="$XDG_CONFIG_HOME/vim/vimrc" | source $MYVIMRC' # shellcheck disable=SC1091 # /etc/profile is provided by macOS. [ "$(uname)" == "Darwin" ] && { PATH=""; source /etc/profile; } -prepend_dir() { # 1: dir to add, 2: variable to manipulate - [ -d "$1" ] && [ -n "$2" ] || return - local list="${!2}" # capture current value - list=${list#"$1:"} # remove dir from beginning - list=${list//":$1:"/:} # remove dir from middle - list=${list%":$1"} # remove dir from end - printf -v "$2" "$1${list:+":$list"}" # add in front (use : only if empty) +_prepend_path() { # 1: dir to add, 2: path variable to manipulate + if [ -d "$1" ] && [ -n "$2" ]; then + local _path="${!2}" # get path variable value + case ":$_path:" in + *":$1:"*) :;; # dir already in path, noop (:) + *) _path="$1${_path:+:}$_path";; # prepend (adding : if not empty) + esac + printf -v "$2" "%s" "$_path" # write back to path variable + fi } # Add custom bin dirs to PATH if they exist and are not already in PATH. -while read -r dir; do prepend_dir "$dir" PATH; done <