bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bash $@ Parameter Variable Breaking Out of Strings


From: Chet Ramey
Subject: Re: Bash $@ Parameter Variable Breaking Out of Strings
Date: Tue, 22 Mar 2016 11:18:51 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Thunderbird/38.6.0

On 3/22/16 10:47 AM, Adam Danischewski wrote:
> I noticed an issue using the parameter built-in variable $@ breaking
> out of contained strings when utilized in functions.
> 
> For example, consider the following bash script: m.bsh
> #!/bin/bash
> echo "$#"
> while getopts d: OPTION "$@"; do
>  case "$OPTION" in
>    d)
>      echo "the optarg is ${OPTARG##*=}, optind is ${OPTIND}"
>      [[ -z "${OPTARG}" ]] && echo "Let's set the null byte as the delim."
>     ;;
>  esac
> done
> exit 0
> 
> $alias t1='_() { var=$@; /tmp/m.bsh -d "clarify ${var}"; }; _'
> $t1 hi there
> 2
> the optarg is clarify hi there, optind is 3 
>  ### Correctly considers the text as a single string argument
>      containing a space.

The $@ is expanded in a context where word splitting is not performed.
There has actually been a lot of discussion about this case on the
Posix shell standardization mailing list.

> 
> $alias t2='_() { /tmp/m.bsh -d "clarify $@"; }; _'
> $ t2 hi there
> 3
> the optarg is clarify hi, optind is 3
>  ### Incorrectly breaks the argument array variable out as separate
>      single string arguments.

I'm not sure why you think this is a problem.  When $@ occurs in double
quotes, it expands to multiple words, one for each positional parameter,
combined with the portions of the string before and after it.  "$@" always
expands to multiple words if there are multiple positional parameters and
word splitting is performed.

> I noticed another interesting occurrence as well, I'm not sure if they are
> related, to variable names:
> 
> function update() {
> local -i VAR=45
> VAR+=-1
> VAR+=$1
> echo $VAR
> }
> 
> $ VAR2=2
> $ update VAR2
>   47
> 
> $ VAR=3
> $ update VAR
>  88 ### !? 

There's no mystery here.  When a variable name is used in arithemtic
evaluation context, its value is expanded as an expression.  Since VAR is
an integer variable, the rhs of any assignment to it is considered an
arithmetic expression and evaluated as such.

So what you end up with is

local -i VAR=45         # VAR = 45
VAR+=-1                 # VAR = 44, local var takes precedence
VAR+=VAR                # VAR += 44 --> VAR = 88, local var used

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU    chet@case.edu    http://cnswww.cns.cwru.edu/~chet/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]