Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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

share|improve this question
    
How to format the citation block like a man page? –  Kanvuanza Oct 12 '12 at 2:14
1  
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? –  Kanvuanza 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
3  
Why do you want to do this? Sounds like an XY problem –  glenn jackman Oct 12 '12 at 15:55
show 1 more comment

2 Answers

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[@]}"
share|improve this answer
add comment

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
do
    param="$(printf %s. "$1" | tr -s "/")"
    set -- "$@" "${param%.}"
    shift
done
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
add comment

Your Answer

 
discard

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.