small question

Hi there,

I found the following script on the net, i like to use it as a standard template for new scripts.

But i do not understand the meaning of the last line, can anybody explain what going on on the last line

vflag=off
filename=
while getopts vf: opt
do
case "$opt" in
v) vflag=on;;
f) filename="$OPTARG";;
\?) # unknown flag
echo >&2 \
"usage: $0 [-v] [-f filename] [file ...]"
exit 1;;
esac
done
shift `expr $OPTIND - 1`

I too did not get it.. but what i understand is that the shift command shifts the parameter to one position.

Generally we can specify a number next to shift command and the parameters are shifted to that many positions..

Reading the man page for getopts may help you understand .. didn't work for me :wink:

In the man page, there is an example that uses shift `expr $OPTIND - 1` at the end. It says "The shift command allows the shell program to continue to process any other arguments." I'm not sure if by arguments it means multiple options (like -v and -f at the same time) or option-arguments (like -f "file1 file2").

I tried the script and modified it to display the first two lines of any file(s) specified with the -f option.

It worked fine whether I kept the line shift `expr $OPTIND - 1` in there or not...

I tried:
script -f "testFile testFile2"
script -f testFile -f testFile2

With the -v .. without the -v .. I can't figure what difference that last line makes.. :confused:

Suppose you invoke a script like this:
./script -abc -d13 -xyz file1 file2 file3

getopts will pull the options apart and deliver them to you one by one. So you will get a, b, c, d 13, x, y, and z.

Your script would use these options to set various internal flags and switches. Then it wants to get the rest of the parameters. This will be the file1, file2, file3.

This is where that shift comes in. That's how the scipt steps over the options to the rest of the parameters.

If there are no trailing parameters after the options, then yeah, no need for the shift.

From what you're saying Perderabo, I should have seen some difference, then, when I removed that last line and entered the commands I did versus when I left that last line in there.

But I didn't...

Post your code.

I didn't post it because it's the same as what janr posted with a couple additions:

vflag=off
filename=
while getopts vf: opt
do
case "$opt" in
v) vflag=on
echo 'vflag is on';;
f) filename="$OPTARG"
head -n 2 $filename;;
\?) # unknown flag
echo >&2 \
"usage: $0 [-v] [-f filename] [file ...]"
exit 1;;
esac
done
echo $OPTIND
shift `expr $OPTIND - 1`

Well there's your problem...you don't do anything at all after the shift. Not even one line of code. Sure enough, if you don't do anything after the shift then there's no point. If you want to notice the difference you must attempt to use the remaining arguments.

Thanks, Perderabo, now I get it. :slight_smile:

Thank you all