On 3/4/2019 5:16 AM, Greg Wooledge wrote: > On Sat, Mar 02, 2019 at 08:47:43PM -0800, L A Walsh wrote: > >> hb=~law/bin (line#4) >> > > Well, that's just a syntax error. > --- Sorry, the '(line#4)' was editorial commenting (vs. actual commenting) > >> if ! [[ $hb =~ $PATH ]]; then export PATH="$hb:$hl:$PATH"; fi >> > > What is the logic behind that regex check? It looks completely wrong. > > If the intent of this code is "check whether $hb is already in $PATH", > then this code is incorrect. > Hi Greg!
1) You're right, the order is reversed. Thank-you! 2) It usually doesn't matter in my case, since my PATH usually contains both of those paths. (BTW, to give you an idea of why I used these names, 'h':home, '{b,l}:{bin,lib}'. So, probably, just reversing the order should be sufficient for my purposes. Strictly speaking, whether or not they are in my path is unrelated to the problem, which is another reason why I didn't pay too much attention to it, but more than once I've reversed the order. In scripts where this needs to be correct, I use functions that I've written to avoid my having to remember (only used to init the environment @ login or when .bashrc is called): Try these for functionality (not necessarily optimal): # if needed, uncomment: # shopt -s bash_aliases # required for POSIX-compat shell # alias my='declare ' int='my -i ' array='my -a ' map='my -A ' # NOTE: only handles 1 pathname at a time # empty defined as 1) not existing, 2) for dirs: nothing in dir # 3) for files: size 0 sub _path_empty { my _abort=exit [[ $0 =~ bash$ ]] && _abort=return if (($#>1)); then printf "FATAL internal error: _path_empty only takes 1 arg, not %d\n" $# [[ $0 =~ bash$ ]] && return 1; exit 1 fi my _ng_savestate=$(shopt -p nullglob) shopt -s nullglob int true=0 false=1 int _empty=true if [[ ! -e $1 ]]; then _empty=true elif [[ -f $1 && -s $1 ]]; then _empty=false elif [[ -d $1 ]]; then array _entries=("$1"/*) ((${#_entries[@]})) && _empty=false fi $_ng_savestate return $_empty } _path_has_subpath() { [[ ${!1} =~ :$2:|^$2:|:$2$ ]] ; } # _path_op CODE ['!'] PATHVarName # - in 'delete' case (uses '!'), status from path_has_subpath is toggled # this means P_H_S becomes check for path NOT having subpath # 'code' = shell script options to perform # 'pathVarName' = "path-like" VarName (ex. PATH or LD_LIBRARY_PATH) _path_op() { (($#<3)) && return 1 my code=$1 pathVarName=$2; shift 2 int del=0 [[ ${pathVarName:-} == ! ]] && { del=1 ; pathVarName=$1 ; shift ; } if ((!${#code} || !${#pathVarName})); then echo >&2 "_path_op: bad args"; sleep 1;return 1; fi while (($#)); do if [[ -d $1 ]] && ! _path_empty "$1"; then { _path_has_subpath "$pathVarName" "$1" ; ((!($?^$del))) ; } || { eval "$(set "$pathVarName" "$1"; eval "echo $code")" } fi shift; done } # called with name of path (ex. 'PATH' & one or more sub paths # each of these prepend an "assign FORMAT" to the passed-in PATHVAR + pathcomp _path_delete() { _path_op '$1=\"${!1//@(^$2:|:$2$)|$2:/}\"' '!' "$@" ; } _path_append() { _path_op '$1=\"${!1}${!1:+:}$2\"' "$@" ; } _path_prepend() { _path_delete "$1" "$2"; _path_op '$1=\"$2${!1:+:}${!1}\"' "$@" ; } export -f _path_append _path_prepend _path_has_subpath _path_op _path_delete _path_empty