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
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?
- Simon
Index: bin/ksh/ksh.1
===================================================================
RCS file: /cvs/src/bin/ksh/ksh.1,v
retrieving revision 1.219
diff -u -r1.219 ksh.1
--- bin/ksh/ksh.1 10 Jun 2023 07:24:21 -0000 1.219
+++ bin/ksh/ksh.1 30 Aug 2023 18:41:27 -0000
@@ -3219,7 +3219,7 @@
?) echo "Usage: ..."; exit 2 ;;
esac
done
-shift $(($OPTIND - 1))
+shift $((OPTIND - 1))
echo "Non-option arguments: " "$@"
.Ed
.Pp
Index: bin/ksh/sh.1
===================================================================
RCS file: /cvs/src/bin/ksh/sh.1,v
retrieving revision 1.157
diff -u -r1.157 sh.1
--- bin/ksh/sh.1 13 May 2023 18:34:49 -0000 1.157
+++ bin/ksh/sh.1 30 Aug 2023 18:41:27 -0000
@@ -524,7 +524,7 @@
?) echo "Usage: ..."; exit 2 ;;
esac
done
-shift $(($OPTIND - 1))
+shift $((OPTIND - 1))
echo "Non-option arguments: " "$@"
.Ed
.It Ic hash Op Fl r | Ar utility
Index: distrib/miniroot/install.sub
===================================================================
RCS file: /cvs/src/distrib/miniroot/install.sub,v
retrieving revision 1.1255
diff -u -r1.1255 install.sub
--- distrib/miniroot/install.sub 21 Aug 2023 14:33:55 -0000 1.1255
+++ distrib/miniroot/install.sub 30 Aug 2023 18:41:27 -0000
@@ -3507,7 +3507,7 @@
*) usage;;
esac
done
-shift $((OPTIND-1))
+shift $((OPTIND - 1))
(($# == 0)) || usage
# The installer can be started by using the symbolic links 'install', 'upgrade'
Index: etc/netstart
===================================================================
RCS file: /cvs/src/etc/netstart,v
retrieving revision 1.234
diff -u -r1.234 netstart
--- etc/netstart 18 Dec 2022 15:52:52 -0000 1.234
+++ etc/netstart 30 Aug 2023 18:41:28 -0000
@@ -354,7 +354,7 @@
*) usage;;
esac
done
-shift $((OPTIND-1))
+shift $((OPTIND - 1))
if ifconfig lo0 inet6 >/dev/null 2>&1; then
IP6KERNEL=true
Index: etc/rc.d/rc.subr
===================================================================
RCS file: /cvs/src/etc/rc.d/rc.subr,v
retrieving revision 1.160
diff -u -r1.160 rc.subr
--- etc/rc.d/rc.subr 19 Oct 2022 21:04:45 -0000 1.160
+++ etc/rc.d/rc.subr 30 Aug 2023 18:41:28 -0000
@@ -327,7 +327,7 @@
*) _rc_usage;;
esac
done
-shift $((OPTIND-1))
+shift $((OPTIND - 1))
_RC_RUNDIR=/var/run/rc.d
_RC_RUNFILE=${_RC_RUNDIR}/${_name}
Index: sys/arch/sparc64/stand/bootblk/genassym.sh
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/stand/bootblk/genassym.sh,v
retrieving revision 1.4
diff -u -r1.4 genassym.sh
--- sys/arch/sparc64/stand/bootblk/genassym.sh 2 Apr 2020 06:06:22 -0000
1.4
+++ sys/arch/sparc64/stand/bootblk/genassym.sh 30 Aug 2023 18:41:57 -0000
@@ -51,7 +51,7 @@
;;
esac
done
-shift "$(($OPTIND - 1))"
+shift $((OPTIND - 1))
if [ $# -eq 0 ]; then
usage
exit 1
Index: usr.bin/compress/znew
===================================================================
RCS file: /cvs/src/usr.bin/compress/znew,v
retrieving revision 1.3
diff -u -r1.3 znew
--- usr.bin/compress/znew 22 Jul 2005 09:34:16 -0000 1.3
+++ usr.bin/compress/znew 30 Aug 2023 18:41:59 -0000
@@ -117,7 +117,7 @@
esac
done
-shift OPTIND-1
+shift $((OPTIND - 1))
if test $# -eq 0; then
echo "$usage"
Index: usr.bin/diff3/diff3.ksh
===================================================================
RCS file: /cvs/src/usr.bin/diff3/diff3.ksh,v
retrieving revision 1.6
diff -u -r1.6 diff3.ksh
--- usr.bin/diff3/diff3.ksh 28 Sep 2019 17:30:07 -0000 1.6
+++ usr.bin/diff3/diff3.ksh 30 Aug 2023 18:41:59 -0000
@@ -45,7 +45,7 @@
;;
esac
done
-shift $(( $OPTIND - 1 ))
+shift $((OPTIND - 1))
if [ $# -lt 3 ]; then
echo "$USAGE" 1>&2
Index: usr.bin/spell/spell.ksh
===================================================================
RCS file: /cvs/src/usr.bin/spell/spell.ksh,v
retrieving revision 1.12
diff -u -r1.12 spell.ksh
--- usr.bin/spell/spell.ksh 25 Jan 2019 00:19:26 -0000 1.12
+++ usr.bin/spell/spell.ksh 30 Aug 2023 18:41:59 -0000
@@ -88,7 +88,7 @@
;;
esac
done
-shift $(( $OPTIND - 1 ))
+shift $((OPTIND - 1))
while test $# -ne 0; do
case "$1" in
Index: usr.sbin/rcctl/rcctl.sh
===================================================================
RCS file: /cvs/src/usr.sbin/rcctl/rcctl.sh,v
retrieving revision 1.117
diff -u -r1.117 rcctl.sh
--- usr.sbin/rcctl/rcctl.sh 13 Jul 2023 13:54:27 -0000 1.117
+++ usr.sbin/rcctl/rcctl.sh 30 Aug 2023 18:42:00 -0000
@@ -512,7 +512,7 @@
*) usage;;
esac
done
-shift $((OPTIND-1))
+shift $((OPTIND - 1))
[ $# -gt 0 ] || usage
action=$1
Index: usr.sbin/sysmerge/sysmerge.sh
===================================================================
RCS file: /cvs/src/usr.sbin/sysmerge/sysmerge.sh,v
retrieving revision 1.235
diff -u -r1.235 sysmerge.sh
--- usr.sbin/sysmerge/sysmerge.sh 28 Sep 2019 17:30:07 -0000 1.235
+++ usr.sbin/sysmerge/sysmerge.sh 30 Aug 2023 18:42:00 -0000
@@ -620,7 +620,7 @@
*) usage;;
esac
done
-shift $(( OPTIND -1 ))
+shift $((OPTIND - 1))
[[ $# -ne 0 ]] && usage
[[ $(id -u) -ne 0 ]] && echo "${0##*/}: need root privileges" && exit 1
Index: usr.sbin/sysupgrade/sysupgrade.sh
===================================================================
RCS file: /cvs/src/usr.sbin/sysupgrade/sysupgrade.sh,v
retrieving revision 1.48
diff -u -r1.48 sysupgrade.sh
--- usr.sbin/sysupgrade/sysupgrade.sh 8 Jun 2022 09:03:11 -0000 1.48
+++ usr.sbin/sysupgrade/sysupgrade.sh 30 Aug 2023 18:42:00 -0000
@@ -99,7 +99,7 @@
set -A _KERNV -- $(sysctl -n kern.version |
sed 's/^OpenBSD \([1-9][0-9]*\.[0-9]\)\([^ ]*\).*/\1 \2/;q')
-shift $(( OPTIND -1 ))
+shift $((OPTIND - 1))
case $# in
0) MIRROR=$(sed 's/#.*//;/^$/d' /etc/installurl) 2>/dev/null ||