Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

    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 --.

share|improve this question
How to format the citation block like a man page? – Pedro Lacerda Oct 12 '12 at 2:14
You can just pass the parent $@ explicitly to the function: func "$@". – jw013 Oct 12 '12 at 2:42
And if I need to rewrite it? – Pedro Lacerda Oct 12 '12 at 2:48
I don't understand what you are asking. What are you trying to do? – jw013 Oct 12 '12 at 3:35
Why do you want to do this? Sounds like an XY problem – glenn jackman Oct 12 '12 at 15:55

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
  … # work on the positional parameters
  eval "$_myfunction_arrayname=(\"\$@\")"
myfunction foo "$@"
set -- "${foo[@]}"
share|improve this answer

Here's some code which loops through the parameters, updating each of them as necessary. In this case, replacing duplicate slashes with a single one:

for param
    param="$(printf %s. "$1" | tr -s "/")"
    set -- "$@" "${param%.}"
share|improve this answer
Off topic question, but why not set -- "${@//\/+(\/)//}" instead of all that? (Note that requires shopt -s extglob, which is off by default for non-interactive shells.) – manatwork Oct 17 '12 at 10:06
@manatwork Nice one-liner for this specific situation. It's just a (verbose) demonstration of how to do arbitrary modification to the parameters. – l0b0 Oct 17 '12 at 10:46

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.