Explain the shell command: shift $(($optind - 1))
shift $((OPTIND-1))
(note OPTIND
is upper case) is normally found immediately after a getopts
while
loop. $OPTIND
is the number of options found by getopts
.
As pauljohn32 mentions in the comments, strictly speaking, OPTIND
gives the position of the next command line argument.
From the GNU Bash Reference Manual:
getopts optstring name [args]
getopts
is used by shell scripts to parse positional parameters.optstring
contains the option characters to be recognized; if a character is followed by a colon, the option is expected to have an argument, which should be separated from it by whitespace. The colon (‘:’) and question mark (‘?’) may not be used as option characters. Each time it is invoked,getopts
places the next option in the shell variable name, initializingname
if it does not exist, and the index of the next argument to be processed into the variableOPTIND
.OPTIND
is initialized to 1 each time the shell or a shell script is invoked. When an option requires an argument, getopts places that argument into the variableOPTARG
. The shell does not resetOPTIND
automatically; it must be manually reset between multiple calls togetopts
within the same shell invocation if a new set of parameters is to be used.When the end of options is encountered,
getopts
exits with a return value greater than zero.OPTIND
is set to the index of the first non-option argument, and name is set to ‘?’.
getopts
normally parses the positional parameters, but if more arguments are given inargs
,getopts
parses those instead.
shift
n
removes n strings from the positional parameters list. Thus shift $((OPTIND-1))
removes all the options that have been parsed by getopts
from the parameters list, and so after that point, $1
will refer to the first non-option argument passed to the script.
Update
As mikeserv mentions in the comment, shift $((OPTIND-1))
can be unsafe. To prevent unwanted word-splitting etc, all parameter expansions should be double-quoted. So the safe form for the command is
shift "$((OPTIND-1))"
$((...))
just calculates stuff. In your case it takes the value of $optint
and substracts 1.
shift
removes positional parameters. In your case it removes optint-1
parameters.
For more information have a look at help getopts
, help shift
, look at man bash
for "Arithmetic Expansion", and especially google for getopts
.