Dan Douglas wrote: > Can you whittle this down to the smallest reproducer and post a stand-alone > synthetic testcase with sample input data that fails? ---- If I had a clue how to do that, I would, that's why I mentioned that that **NORMALLY** it works fine.
include was designed to search the path for functions that are relative paths. While the normal sourcepath allows searching for filenames on the search path, I don't believe (please correct if I am wrong and this works now, as it would make life much simpler) that the PATH will be searched if you give it something like: source lib/Util/sourcefile.shh I can work around things in lib by putting 'lib' in my path, but for things not at the first level... exporting arrays (and Hashes) was something to make USE of, not a goal. I wanted to be able to store arbitrary pathnames and the only way to do that easily is to have them in arrays, since you can't use '\000' as a separator. I had similar requirements for group names -- I wanted to test for group membership by name, so I can use Hashes to test if something 'should' work (actual file permissions will decide security), but the HASH'ed group tests are to give messages about needing to be in such and such a group or whether or not to go ahead and try. Attempting to falsify the _GROUPS_ array would only lead to ugly error messages. ;-) echo ${_GROUPS_[Remote Desktop Users]} 555 echo ${_GROUPS_[Domain Admins]} 512 I also use similar methods for propagating aliases like int=declare\ -i array=declare\ -a sub=function my=declare etc... 'int' and 'sub' are the most useful ones... > > If the goal is simulating "exported arrays", there are other methods that > would probably work out better. --- Well, if that isn't the goal, but the above are goals, do your methods apply equally well? Without NULL as a separator, arrays are the only way to store things without lots of quoting, but they are very difficult to use ... Try pulling out a groupid from a groupname without a hash...it is doable, but not nearly so simply. I've *lived* with the reported bug for at least several months, because I couldn't figure out why it failed there but not elsewhere. It only *fails* when including 'needroot.shh'... But these two work: > cd /tmp > include stdalias.shh #include file or lib/file are generally > equivalent > include lib/stdlib.shh > include Util/urlparts.shh # but this one - Util is a subdir of 'lib' > (i.e. not in path) > echo ${_INC[@]} ## keeps track of what has been included so a subsequent > include won't reinclude /home/law/bin/lib/stdlib.shh /home/law/bin/lib/Util/urlparts.shh /home/law/bin/lib/stdalias.shh #i.e.: > echo ${_INC[stdalias.shh]} /home/law/bin/lib/stdalias.shh The calling script CAN be simple: #!/bin/bash include Util/needroot.shh whoami > tryroot ./tryroot: line 7: Util/needroot.shh: syntax error: invalid arithmetic operator (error token is ".shh") law --- or if I do include lib/Util/needroot.shh I get the div by 0: > cat zroot #!/bin/bash include lib/Util/needroot.shh whoami > zroot ./zroot: line 7: lib/Util/needroot.shh: division by 0 (error token is "/needroot.shh") law ---- Util/needroot.shh works when sourced: > cat >do_root #!/bin/bash source ~/lib/Util/needroot.shh whoami Ishtar:tmp> +x do_root Ishtar:tmp> do_root root ---- Oddly, it happens w/needroot even when it doesn't re-execute itself (i.e. already running as root!) (but only if it needs to access it via the PATH -- if I'm in a dir like bin, and needroot is in bin/lib/Util/needroot.shh then it works! needroot.shh: #!/bin/bash shift declare -xi _needroot+=1 sudo="$(type -P sudo 2>/dev/null)" if [[ $sudo == "" || ! -e $sudo ]]; then ((_needroot<2)) && echo "warning: sudo not found, executing as normal user..." >&2 exit 0 else # echo "UID=$UID, EUID=$EUID" if ((EUID)); then ((_needroot<2)) && exec $(eval echo sudo "$0" "$@") echo "Need root: Fatal error" >&2 exit -1 fi fi ((1)) ------------------- function include: declare -A _INC export _INC function include { [[ $1 ]] || return 1 local fnc="$1" [[ $PATH != ${_SPATH:-} || ${#_FPATH[@]} -lt 1 ]] && { unset _FPATH local -xa _FPATH=( $(IFS=:;echo $PATH) ) export _SPATH="$PATH" } # function seems to exit here when including needroot when it's not given via a relative name # i.e. would need to find it off of the PATH if [[ -z ${_INC["${fnc:-}"]:-} ]]; then local pw for pw in "${_FPATH[@]}"; do [[ ${pw:0-1:1} != / ]] && pw+='/' local fn="${pw}${fnc}" if [[ -r $fn || -r $fn.shh && fn="$fn.shh" ]]; then source "$fn" || { stat=$? echo "Error: include of \"$fnc\" did not return 0 status" return $stat } _INC["$fnc"]="$fn" return 0 fi done echo "Cannot find \"$fnc\" in \"$PATH\"" >&2 exit 2 fi } export -f include ---------------------------- Those are the basic parts....