Skip to main content
added 486 characters in body
Source Link
Stéphane Chazelas
  • 584.6k
  • 96
  • 1.1k
  • 1.7k

With recent versions of bash, you could use namerefs:

arrLen() {
  typeset -n __Var="$1"
  echo "${#__Var[@]}"
}

Here we choose __Var as the nameref variable name, as one that is unlikely to be used otherwise within your script. arrLen __Var fails with circular name reference errors.

Namerefs (like typeset, and bash's array design in general) is a feature that bash borrowed from the Korn shell. In ksh (ksh93 where namerefs were introduced), you'd write:

function arrLen {
  typeset -n var="$1"
  echo "${#var[@]}"
}

(ksh namerefs are able to reference a variable with the same name from the caller's scope (or the global scope), but scoping (static scoping) is only done in functions declared with the Korn syntax, not with the Bourne syntax)

Or you can always use eval to construct code dynamically.

arrLen() {
  eval 'echo "${#'"$1"'[@]}"'
}

With zsh:

arrLen() echo ${(P)#1}

bash Nameref resolution, zsh's P parameter expansion flag also do some form of eval (dynamic code evaluation) under the hood, so all those approaches are equally unsafe if the argument passed to arrLen is not guaranteed to be a valid variable name, but equally safe if they are.

With recent versions of bash, you could use namerefs:

arrLen() {
  typeset -n __Var="$1"
  echo "${#__Var[@]}"
}

Here we choose __Var as the nameref variable name, as one that is unlikely to be used otherwise within your script. arrLen __Var fails with circular name reference errors.

Or you can always use eval to construct code dynamically.

arrLen() {
  eval 'echo "${#'"$1"'[@]}"'
}

With zsh:

arrLen() echo ${(P)#1}

bash Nameref resolution, zsh's P parameter expansion flag also do some form of eval (dynamic code evaluation) under the hood, so all those approaches are equally unsafe if the argument passed to arrLen is not guaranteed to be a valid variable name, but equally safe if they are.

With recent versions of bash, you could use namerefs:

arrLen() {
  typeset -n __Var="$1"
  echo "${#__Var[@]}"
}

Here we choose __Var as the nameref variable name, as one that is unlikely to be used otherwise within your script. arrLen __Var fails with circular name reference errors.

Namerefs (like typeset, and bash's array design in general) is a feature that bash borrowed from the Korn shell. In ksh (ksh93 where namerefs were introduced), you'd write:

function arrLen {
  typeset -n var="$1"
  echo "${#var[@]}"
}

(ksh namerefs are able to reference a variable with the same name from the caller's scope (or the global scope), but scoping (static scoping) is only done in functions declared with the Korn syntax, not with the Bourne syntax)

Or you can always use eval to construct code dynamically.

arrLen() {
  eval 'echo "${#'"$1"'[@]}"'
}

With zsh:

arrLen() echo ${(P)#1}

bash Nameref resolution, zsh's P parameter expansion flag also do some form of eval (dynamic code evaluation) under the hood, so all those approaches are equally unsafe if the argument passed to arrLen is not guaranteed to be a valid variable name, but equally safe if they are.

added 181 characters in body
Source Link
Stéphane Chazelas
  • 584.6k
  • 96
  • 1.1k
  • 1.7k

With recent versions of bash, you could use namerefs:

arrLen() {
  typeset -n __Var="$1"
  echo "${#__Var[@]}"
}

Here we choose __Var as the nameref variable name, as one that is unlikely to be used otherwise within your script. arrLen __Var fails with circular name reference errors.

Or you can always use eval to construct code dynamically.

arrLen() {
  eval 'echo "${#'"$1"'[@]}"'
}

With zsh:

arrLen() echo ${(P)#1}

bash Nameref resolution, zsh's P parameter expansion flag also do some form of eval (dynamic code evaluation) under the hood, so all those approaches are equally unsafe if the argument passed to arrLen is not guaranteed to be a valid variable name, but equally safe if they are.

With recent versions of bash, you could use namerefs:

arrLen() {
  typeset -n __Var="$1"
  echo "${#__Var[@]}"
}

Or you can always use eval to construct code dynamically.

arrLen() {
  eval 'echo "${#'"$1"'[@]}"'
}

With zsh:

arrLen() echo ${(P)#1}

bash Nameref resolution, zsh's P parameter expansion flag also do some form of eval (dynamic code evaluation) under the hood, so all those approaches are equally unsafe if the argument passed to arrLen is not guaranteed to be a valid variable name, but equally safe if they are.

With recent versions of bash, you could use namerefs:

arrLen() {
  typeset -n __Var="$1"
  echo "${#__Var[@]}"
}

Here we choose __Var as the nameref variable name, as one that is unlikely to be used otherwise within your script. arrLen __Var fails with circular name reference errors.

Or you can always use eval to construct code dynamically.

arrLen() {
  eval 'echo "${#'"$1"'[@]}"'
}

With zsh:

arrLen() echo ${(P)#1}

bash Nameref resolution, zsh's P parameter expansion flag also do some form of eval (dynamic code evaluation) under the hood, so all those approaches are equally unsafe if the argument passed to arrLen is not guaranteed to be a valid variable name, but equally safe if they are.

added 121 characters in body
Source Link
Stéphane Chazelas
  • 584.6k
  • 96
  • 1.1k
  • 1.7k

With recent versions of bash, you could use namerefs:

arrLen() {
  typeset -n __Var="$1"
  echo "${#__Var[@]}"
}

Or you can always use eval to construct code dynamically.

arrLen() {
  eval 'echo "${#'"$1"'[@]}"'
}

With zsh:

arrLen() echo ${(P)#1}

bash Nameref referencingresolution, zsh's P parameter expansion flag also doesdo some form of eval (dynamic code evaluation) under the hood, so the twoall those approaches are equally unsafe if the argument passed to arrLen is not guaranteed to be a valid variable name, but equally safe if they are.

With recent versions of bash, you could use namerefs:

arrLen() {
  typeset -n __Var="$1"
  echo "${#__Var[@]}"
}

Or you can always use eval to construct code dynamically.

arrLen() {
  eval 'echo "${#'"$1"'[@]}"'
}

Nameref referencing also does some form of eval (dynamic code evaluation) under the hood, so the two approaches are equally unsafe if the argument passed to arrLen is not guaranteed to be a valid variable name.

With recent versions of bash, you could use namerefs:

arrLen() {
  typeset -n __Var="$1"
  echo "${#__Var[@]}"
}

Or you can always use eval to construct code dynamically.

arrLen() {
  eval 'echo "${#'"$1"'[@]}"'
}

With zsh:

arrLen() echo ${(P)#1}

bash Nameref resolution, zsh's P parameter expansion flag also do some form of eval (dynamic code evaluation) under the hood, so all those approaches are equally unsafe if the argument passed to arrLen is not guaranteed to be a valid variable name, but equally safe if they are.

Source Link
Stéphane Chazelas
  • 584.6k
  • 96
  • 1.1k
  • 1.7k
Loading