Debugging shell scripts can be done with echo or set -x. The latter, when placed near the top of a script will produce lots of output, so here is a driver script that puts your echo-augmented script through its paces:
#!/bin/bash -
# @(#) s1 Demonstrate getopts.
echo
echo "(Versions displayed with local utility \"version\")"
version >/dev/null 2>&1 && version =o $(_eat $0 $1)
set -o nounset
echo
U=./user1
echo " Contents of script $U:"
cat $U
echo
echo " For plain:"
$U
echo
echo " For illegal argument:"
$U -z
echo
echo " For missing option-arguments:"
$U -i
$U -l
echo
echo " For legitimate option arguments:"
$U -ix -l y -- file1 file2
exit 0
Producing:
% ./s1
(Versions displayed with local utility "version")
Linux 2.6.11-x1
GNU bash 2.05b.0
Contents of script ./user1:
#!/bin/bash
lflag=
iflag=
while getopts 'l:i:' OPTION
do
case $OPTION in
l) lflag=1
lval="$OPTARG"
;;
i) iflag=1
ival="$OPTARG"
;;
?) printf "Usage: %s: [-a] [-b value] args\n" $(basename $0) >&2
exit 2
;;
esac
done
shift $(($OPTIND - 1))
echo
echo " iflag = $iflag, ival = $ival; lflag = $lflag, lval = $lval"
echo
echo " Remaining command line:"
echo $*
For plain:
iflag = , ival = ; lflag = , lval =
Remaining command line:
For illegal argument:
./user1: illegal option -- z
Usage: user1: [-a] [-b value] args
For missing option-arguments:
./user1: option requires an argument -- i
Usage: user1: [-a] [-b value] args
./user1: option requires an argument -- l
Usage: user1: [-a] [-b value] args
For legitimate option arguments:
iflag = 1, ival = x; lflag = 1, lval = y
Remaining command line:
file1 file2
The driver script lists your script, then tests it. As you can see, I've added a few echo statements. The results look OK to me, so I'd guess you called it in an unconventional way.
As an aside: using l (ell), 1 (one), and i (eye) can be confusing to the user of a script because in many typefaces they all look very similar.