#!/bin/bash # saner programming env: these switches turn some bugs into errors set -o errexit -o pipefail -o noclobber -o nounset source="-" dest="-" verbose=true help=false GetOptions() { # https://stackoverflow.com/a/29754866 ! getopt --test > /dev/null if [[ ${PIPESTATUS[0]} -ne 4 ]]; then VerboseOutput "Fatal" "\`getopt --test\` failed" echo "Sorry, It seems that your shell is not supported" echo "If you're using mac or another unix-like system, please install GNU getopt" exit 1 fi OPTIONS=s:d:vh LONGOPTS=source:,dest:,verbose,help # -use ! and PIPESTATUS to get exit code with errexit set # -temporarily store output to be able to check for errors # -activate quoting/enhanced mode (e.g. by writing out “--options”) # -pass arguments only via -- "$@" to separate them correctly ! PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@") if [[ ${PIPESTATUS[0]} -ne 0 ]]; then # e.g. return value is 1 # then getopt has complained about wrong arguments to stdout help=true Usage exit 2 fi # read getopt’s output this way to handle the quoting right: eval set -- "$PARSED" verbose=false # now enjoy the options in order and nicely split until we see -- while true; do case "$1" in -v|--verbose) verbose=true shift ;; -h|--help) help=true echo "test" shift ;; -s|--source) source="$2" shift 2 ;; -d|--dest) dest="$2" shift 2 ;; --) shift break ;; *) echo "Programming error" return 3 ;; esac done } VerboseOutput() { if [[ $verbose ]]; then echo "[$1] $2" >&2 fi } GetOptions $@