#!/bin/bash # All the prefixes to consider prefixes=( "$HOME" "$HOME/.local.$(uname -m)" "$HOME/.local" "$HOME/.prefix.$(uname -m)" "$HOME/.prefix" "$HOME"/.gem/ruby/* ) in_array() { local needle=$1; shift local haystack=("$@") local straw for straw in "${haystack[@]}"; do [[ "$needle" == "$straw" ]] && return 0 done return 1 } var_init() { eval "ary_$1=(\$$1)" } var_add() { local varname=ary_$1; shift local var_all="${varname}[@]" local dirs=("$@") local dir for dir in "${dirs[@]}"; do if [[ -d "$dir" ]] && ! in_array "$dir" "${!var_all}"; then eval "$varname=(\"\$dir\" \"\${$var_all}\")" fi done } var_done() { eval "$1=\"\${ary_$1[*]}\"" declare -p $1 } main() { IFS=: # Import existing values var_init PATH var_init MANPATH var_init LD_LIBRARY_PATH var_init RUBYLIB var_init PERL5LIB # Scan through prefixes for prefix in "${prefixes[@]}"; do var_add PATH "$prefix/bin" "$prefix/sbin" var_add MANPATH "$prefix/share/man" var_add LD_LIBRARY_PATH "$prefix"/lib{,32,64} var_add RUBYLIB "$prefix"/lib{,32,64} var_add PERL5LIB "$prefix"/lib{,32,64}/perl5 done # Finally, print the values # The `sed` bit here is the only time we call an external program { var_done PATH var_done MANPATH var_done LD_LIBRARY_PATH var_done RUBYLIB var_done PERL5LIB } | sed 's/^declare \(-\S* \)*//' } main "$@"