Classic Shell Scripting - Arnold Robbins [110]
Now that initializations have been taken care of, we are ready to process the command-line options. This is done in much the same way in all shell scripts: while an argument remains, select a suitable branch of a case statement to process the argument, then shift the argument list down, and continue the loop. Any branch that needs to consume another argument first does a shift. As we have done before, we permit both single- and double-hyphen forms of options, and we allow them to be abbreviated to any unique prefix:
while test $# -gt 0
do
case $1 in
The —all, —cd, —check, and —configure cases save the following argument, discarding any previously saved value:
--all | --al | --a | -all | -al | -a )
shift
ALLTARGETS="$1"
;;
--cd | -cd )
shift
CONFIGUREDIR="$1"
;;
--check | --chec | --che | --ch | -check | -chec | -che | -ch )
shift
CHECKTARGETS="$1"
;;
--configure | --configur | --configu | --config | --confi | \
--conf | --con | --co | \
-configure | -configur | -configu | -config | -confi | \
-conf | -con | -co )
shift
CONFIGUREFLAGS="$1"
;;
The —environment option provides a way to supply one-time settings of configure-time environment variables on the build host, without having to change build configuration files:
--environment | --environmen | --environme | --environm | --environ | \
--enviro | --envir | --envi | --env | --en | --e | \
-environment | -environmen | -environme | -environm | -environ | \
-enviro | -envir | -envi | -env | -en | -e )
shift
EXTRAENVIRONMENT="$1"
;;
The —help case calls one of our yet-to-be-shown functions, and terminates the program:
--help | --hel | --he | --h | '--?' | -help | -hel | -he | -h | '-?' )
usage_and_exit 0
;;
The —logdirectory case also saves the following argument, discarding any saved value:
--logdirectory | --logdirector | --logdirecto | --logdirect | \
--logdirec | --logdire | --logdir | --logdi | --logd | --log | \
--lo | --l | \
-logdirectory | -logdirector | -logdirecto | -logdirect | \
-logdirec | -logdire | -logdir | -logdi | -logd | -log | -lo | -l )
shift
altlogdir="$1"
;;
The altlogdir variable names the directory where all of the build log files are written, if the default location is not desired.
The —on and —source cases merely accumulate arguments, so the user can write -s "/this/dir /that/dir" or -s /this/dir -s /that/dir:
--on | --o | -on | -o )
shift
userhosts="$userhosts $1"
;;
--source | --sourc | --sour | --sou | --so | --s | \
-source | -sourc | -sour | -sou | -so | -s )
shift
altsrcdirs="$altsrcdirs $1"
;;
Because altsrcdirs separates list elements with a space, directories with spaces in their names will not be handled properly; avoid such names.
The —userhosts case also accumulates arguments, but with the additional convenience of checking an alternate directory location, so we relegate the work to a function:
--userhosts | --userhost | --userhos | --userho | --userh | \
--user | --use | --us | --u | \
-userhosts | -userhost | -userhos | -userho | -userh | \
-user | -use | -us | -u )
shift
set_userhosts $1
;;
The —version case displays a version number and exits with a success status code:
--version | --versio | --versi | --vers | --ver | --ve | --v | \
-version | -versio | -versi | -vers | -ver | -ve | -v )
version
exit 0
;;
The next-to-last case catches any unrecognized options and terminates with an error:
-*)
error "Unrecognized option: $1"
;;
The last case matches anything but an option name, so it must be a package name, and we leave the option loop:
*)
break
;;
esac
A shift discards the just-processed argument, and we continue with the next loop iteration:
shift
done
We need a mail-client program to report log-file locations. Unfortunately, some systems have a low-level mail command that does not accept a subject line, but have a mailx command that does. Other systems lack mailx, but have subject-line support in mail.