On Wed, Aug 30, 2023 at 12:31:08PM -0700, Simon Branch wrote: > Hello tech@, > > In an arithmetic substitution -- that is, the $(( ... )) construct in a > shell script -- one can reference variables either with ($a) or without > (a) the dollar sign. However, the latter is slightly better: the > variable is interpreted as an integer, and then the integer is used > inside the expression. With the former, the variable's contents are > spliced into the expression before it is parsed. For example: > > $ a='1+5' > $ echo $((a * 2)) > 12 > $ echo $(($a * 2)) > 11 > > Another gotcha with $(($a)): > > $ echo $((a=2, a)) > 2 > $ echo $((a=3, $a)) # oops, $a was spliced in before the assignment > 2 > > All this to say, $(($a)) should be reserved for where it is required, > not used as the default form. > > The following idiom is used throughout the source tree, including in > sh.1 and ksh.1: > > while getopts ... > ... > done > shift $(($OPTIND - 1)) > > and it has a couple of variations: > > shift $((OPTIND - 1)) my preferred option > shift OPTIND-1 works because ksh is magical > shift $(( OPTIND -1 )) and other silly whitespace conventions > shift "$(($OPTIND - 1))" unnecessary: $(()) evaluates to an integer
About that last one: If it wasn't for the fact that OpenBSD ksh and sh are a bit magical, there would be an issue if $IFS contained a digit. So to protect the code in the pathological case (non-OpenBSD ksh/sh, and $IFS containing digits), the quotes are needed. Now, that's never going to be an issue in shell script in the OpenBSD source tree obviously, but still... I'm an academic. > > My patch changes all of these to the $((OPTIND - 1)) usage, which > encourages good shell practice and is clearly understandable. It > ignores src/gnu since I believe those files are vendored in, and there's > no reason to introduce conflicts when pulling them from upstream. > > Reasonable? Reasonable. But I'm not anyone you need to listen to. -- Andreas (Kusalananda) Kähäri SciLifeLab, NBIS, ICM Uppsala University, Sweden .