Since shell is a rather unpredictable programming language,
which seems not to allow
manipulation of variables in parent processes, parsing
arguments has always been a bit cumbersome. For instance, check out
lines 74 through 123 of /usr/bin/deb-reversion
(package devscripts) for the way I used to do things,
which involves a sort of state machine to handle options taking
arguments.
Just last night, I came up with another means, and while it felt
like an incredible hack at the time, I am starting to like it. This
method can be combined with getopt, I just use it to
parse guessnet test lines in
/etc/network/interfaces right now:
eval $(while [ -n "${1:-}" ]; do
case "$1" in
mac) echo MACADDR="'$2'"; shift;;
essid) echo ESSID="'$2'"; shift;;
ie) echo IE="'$2'"; shift;;
*)
echo "$ME: E: invalid argument: $1" >&2
exit 1;;
esac
shift
done || exit $?) || exit $?
When this is done, any (or none) of the three variables
MACADDR, ESSID, and IE are
defined in the shell script’s environment. If an argument is
required, I can do checks following the loop, or use
getopt to parse $@ before looping over
its components. Of course, the last line really does make it look
like a hack, but it works and it’s flexible…
If I now look at
/usr/share/guessnet/test/test-wireless, I wonder how
Thomas Hood managed to get things working, specifically because he
sets variables inside a while loop, and then uses them
outside of the loop —exactly the sort of
construct that drove me nuts previously. Maybe it has to do
with my religious use of set -u, maybe not. In any
case, I am simply not willing to investigate.

