diff --git a/shopts.sh b/shopts.sh new file mode 100755 index 0000000..a2d7407 --- /dev/null +++ b/shopts.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# ex33.sh: Exercising getopts and OPTIND +# Script modified 10/09/03 at the suggestion of Bill Gradwohl. + + +# Here we observe how 'getopts' processes command-line arguments to script. +# The arguments are parsed as "options" (flags) and associated arguments. + +# Try invoking this script with: +# 'scriptname -mn' +# 'scriptname -oq qOption' (qOption can be some arbitrary string.) +# 'scriptname -qXXX -r' +# +# 'scriptname -qr' +#+ - Unexpected result, takes "r" as the argument to option "q" +# 'scriptname -q -r' +#+ - Unexpected result, same as above +# 'scriptname -mnop -mnop' - Unexpected result +# (OPTIND is unreliable at stating where an option came from.) +# +# If an option expects an argument ("flag:"), then it will grab +#+ whatever is next on the command-line. + +NO_ARGS=0 +E_OPTERROR=85 + +if [ $# -eq "$NO_ARGS" ] # Script invoked with no command-line args? +then + echo "Usage: `basename $0` options (-mnopqrs)" + exit $E_OPTERROR # Exit and explain usage. + # Usage: scriptname -options + # Note: dash (-) necessary +fi + + +while getopts ":mnopq:rs" Option +do + case $Option in + m ) echo "$OPTIND -$Option ($OPTARG)";; + n | o ) echo "$OPTIND -$Option ($OPTARG)";; + p ) echo "$OPTIND -$Option ($OPTARG)";; + q ) echo "$OPTIND -$Option ($OPTARG)";; + # Note that option 'q' must have an associated argument, + #+ otherwise it falls through to the default. + r | s ) echo "$OPTIND -$Option ($OPTARG)";; + * ) echo "Unimplemented option chosen.";; # Default. + esac +done + +shift $(($OPTIND - 1)) +echo "Rest $@" + +# Decrements the argument pointer so it points to next argument. +# $1 now references the first non-option item supplied on the command-line +#+ if one exists. + +exit $? + +# As Bill Gradwohl states, +# "The getopts mechanism allows one to specify: scriptname -mnop -mnop +#+ but there is no reliable way to differentiate what came +#+ from where by using OPTIND." +# There are, however, workarounds. \ No newline at end of file diff --git a/test/main.inc b/test/main.inc new file mode 100755 index 0000000..cf1e801 --- /dev/null +++ b/test/main.inc @@ -0,0 +1,8 @@ + +INC=include +HOST_NAME=$(hostname) + +testfunc() { + echo "testfunc() works!" +} + \ No newline at end of file diff --git a/test/main.sh b/test/main.sh new file mode 100755 index 0000000..8fe24cc --- /dev/null +++ b/test/main.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +show_help() { + echo "usage: $0 options" + echo " -a, --auto start nightly backup" + echo " -l, --list list archives" + echo ' -c, --content ' + echo " show contents of archive" + echo ' -r, --restore ' + echo " restore files from archive to pwd" + echo " -h, -?. --help show this help" +} + +echo " ### main.sh" + +# Initialize all the option variables. +# This ensures we are not contaminated by variables from the environment. +file= +archive= + +while :; do + case $1 in + -h|-\?|--help) + show_help # Display a usage synopsis. + exit 0 + ;; + -a|--auto) + shift + . $HERE/$HOST_NAME.sh "$@" >$LOGF 2>&1 + break # exit kehrt nicht zu run.sh zurück + ;; + -l|--list) + . $HERE/$HOST_NAME.sh -l + break; + ;; + -c|--content) + if [ "$2" ]; then + echo "not yet implemented" + #. $HERE/$HOST_NAME.sh -c $2 + else + echo 'ERROR: "--content" requires a non-empty option argument.' + fi + break + ;; + -r|--restore) + if [ "$2" ]; then + echo "not yet implemented" + archive=$2 + shift + #. $HERE/$HOST_NAME.sh -r $archive $@ + else + echo 'ERROR: "--restore" requires a non-empty option argument.' + fi + break + ;; + + # --- example -> https://mywiki.wooledge.org/BashFAQ/035 + -f|--file) # Takes an option argument; ensure it has been specified. + if [ "$2" ]; then + file=$2 + shift + else + die 'ERROR: "--file" requires a non-empty option argument.' + fi + ;; + --file=?*) + file=${1#*=} # Delete everything up to "=" and assign the remainder. + ;; + --file=) # Handle the case of an empty --file= + die 'ERROR: "--file" requires a non-empty option argument.' + ;; + --) # End of all options. + shift + break + ;; + -?*) + echo "WARN: Unknown option (ignored): $1" + echo + show_help + exit + ;; + *) # Default case: No more options, so break out of the loop. + break + esac + + shift +done + diff --git a/test/nathan.sh b/test/nathan.sh new file mode 100755 index 0000000..bbe6e69 --- /dev/null +++ b/test/nathan.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +echo " *** nathan.sh" +for i in "$@"; do echo "param: $i"; done + +echo " include=$INC" +echo " host=$HOST_NAME" +testfunc +echo " *** nathan.sh end" + diff --git a/test/run.sh b/test/run.sh new file mode 100755 index 0000000..33d6dc3 --- /dev/null +++ b/test/run.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +HERE=$(dirname "$0") +. $HERE/main.inc + +LOGF=$HERE/t1.log + +echo "--- run.sh" + +. $HERE/main.sh "$@" + +echo "--- run.sh end" diff --git a/test/t1.log b/test/t1.log new file mode 100644 index 0000000..e23e4a3 --- /dev/null +++ b/test/t1.log @@ -0,0 +1,10 @@ +testfunc() works! + ### main.sh +usage: ./run.sh options + -a, --auto start nightly backup + -l, --list list archives + -c, --content + show contents of archive + -r, --restore + restore files from archive to pwd + -h, -?. --help show this help