this particular section is not clear to me can anyone please
clarify in a little detail so that i can understand the concept
MANPAGE::
Since getopts affects the current shell execution environ-
ment, it is generally provided as a shell regular built-in.
If it is called in a subshell or separate utility execution
environment, such as one of the following:
\(getopts abc value "$@"\)
nohup getopts ...
find . -exec getopts ... \\;
it does not affect the shell variables in the caller's
environment.
Notice that shell functions share OPTIND with the calling
shell even though the positional parameters are changed.
I am not sure which point you have troubles to understand, so maybe my explanation is superficial - i'll just give it a try:
when you call a script with some parameters these parameters are part of the scripts environment - variables $1, $2, $3, .... - and this environment does not change under normal circumstances (save for explicit changes to it using the "shift" keyword, etc.).
This now changes when you use "getopts" to parse the commandline. "getopts" will do the parsing but after calling it the environment (more precisely: part of it - the parameters special variables) will have no more meaningful content. Example:
echo "$1" # some content
/some/command
echo "$1" # same !! content as before
whereas:
echo "$1" # some content
getopts [.....] "$@"
echo "$1" # NOT the same content as before
To prevent this it is possible to call getopts in a different (child) environment by several means listed in the manpage. When you call a child process the environment of the father process is copied and given to the child (the child "inherits" from the father) - this is why the Nr. 1 reason for cron jobs is the wrong environment: the job is tested in a login shell, which has some environment the inheriting job relies implicitly upon. When it is called not by the login shell but by cron (which has next to no environment, not even a PATH) it fails. This only as n aside.
When getopts is - by the mentioned means - called in a child process it gets a copy of the environment and works on this, therefore not destroying the father process' environment.
The point is not that it has to change, but it might change. You simply cannot rely on the fact that "$1" remains the same before and after getopts - whereas you can rely on, say, "$charley" being the same before and after executing a command.
The meaning of the set-command is simple: "set --" clears the special variables "$1", "$2", etc.:
# cat settest.sh
#!/bin/ksh
echo "first parm is: $1"
echo "second parm is: $2"
echo "third parm is: $3"
set --
echo "first parm is: $1"
echo "second parm is: $2"
echo "third parm is: $3"
exit 0
# ./settest.sh a b c
first parm is: a
second parm is: b
third parm is: c
first parm is:
second parm is:
third parm is:
Therefore the "set -- -2-------" means: first make sure no other commandline parameter is set, regardless of what you enter on the commandline, then set exactly one parameter ("-2") with some argument ("------").