On Thu, Nov 20, 2014 at 7:35 AM, Eduardo A. Bustamante López < dual...@gmail.com> wrote:
> Last try: > > is_defined4() { > declare -p -- "$1" 2>/dev/null >&2 > } > > I think using "${#x[@]}" is still the better solution. You probably just missed [@] in ${#a}? And I actually have declare -p in a code I created but currently don't use. I now consider this other solution better thanks to this discussion. #!/bin/bash if [[ BASH_VERSINFO -lt 3 ]]; then echo "Function needs Bash 3.0 or newer." exit 1 elif [[ BASH_VERSINFO -gt 4 || (BASH_VERSINFO -eq 4 && BASH_VERSINFO[1] -ge 3) ]]; then function is_defined { local -n __r=$1 [[ ${#__r[@]} -gt 0 ]] } else function is_defined { local __r=$1[@]:0:1 __t __t=("${!__r}") [[ ${#__t[@]} -gt 0 ]] } fi declare -A a=(['x']=. ['y']=.); unset 'a[x]' is_defined a && echo "a is defined." || echo "a is not defined." x= is_defined x && echo "x is defined." || echo "x is not defined." y=(1 2 3 4) is_defined y && echo "y is defined." || echo "y is not defined." function z { :; } is_defined z && echo "z is defined." || echo "z is not defined." Test: # for A in 3.0 3.1.1 3.2 4.0 4.1 4.2 4.3 current; do echo "---- $A ----"; bash-"$A" temp.sh; done ---- 3.0 ---- temp.sh: line 16: declare: -A: invalid option declare: usage: declare [-afFirtx] [-p] [name[=value] ...] a is not defined. x is defined. y is defined. z is not defined. ---- 3.1.1 ---- temp.sh: line 16: declare: -A: invalid option declare: usage: declare [-afFirtx] [-p] [name[=value] ...] a is not defined. x is defined. y is defined. z is not defined. ---- 3.2 ---- temp.sh: line 16: declare: -A: invalid option declare: usage: declare [-afFirtx] [-p] [name[=value] ...] a is not defined. x is defined. y is defined. z is not defined. ---- 4.0 ---- a is defined. x is defined. y is defined. z is not defined. ---- 4.1 ---- a is defined. x is defined. y is defined. z is not defined. ---- 4.2 ---- a is defined. x is defined. y is defined. z is not defined. ---- 4.3 ---- a is defined. x is defined. y is defined. z is not defined. ---- current ---- a is defined. x is defined. y is defined. z is not defined. Reference expansion in Bash 2.05b.0 seems broken so I added the version check for it but it's just optional if you'd never run the code in 2.05b. I dislike the idea of adding the test inside the function itself but you can also do that. Adding another version of is_defined for 2.05b may also be good and doable but I no longer find that practical. The Bash 4.3 version is also just optional. And of course if you're conservative you can always add a code that checks if the argument is a valid Bash variable like testing it against ext. pattern [[:alpha:]_]*([[:alnum:]_]) or regex [[:alpha:]_][[:alnum:]_]*. It's just up to you if you want to return false (1) if it's invalid or just send a message and exit the shell. I used lowercase variable names for everyone's preference. Cheers, konsolebox