Skip to content

Instantly share code, notes, and snippets.

@trygveaa
Created March 4, 2016 12:42
Show Gist options
  • Save trygveaa/a8619565404124bd8042 to your computer and use it in GitHub Desktop.
Save trygveaa/a8619565404124bd8042 to your computer and use it in GitHub Desktop.
Shell getopts
#!/bin/sh
test=false
host=localhost
port=6600
while getopts ":th:p:" opt; do
case $opt in
t)
test=true
;;
h)
host="$OPTARG"
;;
p)
port="$OPTARG"
;;
\?)
echo "usage: $0 [-t] [-h host] [-p port] arg1" && exit 1
;;
esac
done
shift $((OPTIND-1))
echo "test: $test"
echo "host: $host"
echo "port: $port"
echo "arg1: $1"
@havardh
Copy link

havardh commented Mar 4, 2016

What does shift $((OPTIND-1)) do?

@trygveaa
Copy link
Author

trygveaa commented Mar 4, 2016

A shell script doesn't differentiate between options and arguments by default, so all the options will be in the argument list as well. This is impractical when you want to use the arguments. An example:

script_without_shift_optind.sh -t -p 6000 arg1 arg2

When running this the argument variables will get these values

$0 script_without_shift_optind.sh
$1 -t
$2 -p
$3 6000
$4 arg1
$5 arg2

Since getopts has already processed the options, we are not interested in those in the argument list anymore. Therefore, we shift the argument list by the same number of places that getopts process (which it stores in the $OPTIND variable) to remove them. After that we end up with:

$0 script_with_shift_optind.sh
$1 arg1
$2 arg2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment