Bash – Function caller positional parameters

bashfunctionparametershellshopt

I need to read and write the positional parameters $@ of a function's caller. The Bash man page says that:

A shell function is an object that is called like a simple command and
executes a compound command with a new set of positional parameters

So $@ is rewritten at every call. I looked for some "special parameter" but found nothing. The shell variable BASH_ARGV seems to solve my problem, however it requires shopt -s extdebug enabled, what isn't the default behavior in my machine neither looks like a option to turn on in production.

extdebug
    If set, behavior intended for use by debuggers is enabled:
    ...
    4.     BASH_ARGC and BASH_ARGV are updated as described in their
           descriptions above.
    ...

Is Bash capable of read or write a function's caller $@ without BASH_ARGV? Do you think that Bash is limited and use another shell for scripting?

Edit: I want a fancy getopt wrapper inside my helper library. So all behavior related to it goes inside a function. No need to check errors or set --.

Best Answer

A function cannot affect its caller's positional parameters. This is by design: positional parameters are meant to be private to the function.

Make your function work on an array.

myfunction () {
  local _myfunction_arrayname=$1
  shift
  … # work on the positional parameters
  eval "$_myfunction_arrayname=(\"\$@\")"
}
myfunction foo "$@"
set -- "${foo[@]}"

In ksh93 and bash, there's a roundabout way to do something approaching by combining an alias and the . (source) builtin with a process substitution. Example.

alias myfunction='. <(echo myfunction_body \"\$@\"; echo set -- "\"\${new_positional_parameters[@]}\"")'

Put the meat of the work of the function in myfunction_body and make it set the array new_positional_parameters. After a call to myfunction, the positional parameters are set to the values that myfunction_body puts in new_positional_parameters.

Related Question