help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Allow getopts to do what is capable with getopt?


From: Bob Proulx
Subject: Re: [Help-bash] Allow getopts to do what is capable with getopt?
Date: Wed, 25 Mar 2015 15:55:38 -0600
User-agent: Mutt/1.5.23 (2014-03-12)

Greg Wooledge wrote:
> Peng Yu wrote:
> > I am referring to util-linux' getopt.
> 
> I do not support the unnecessary addition of this bloat into bash as
> a builtin.

Agreed.  There is no need for getopt as a builtin.

> > getopt is more robust than getopts. Is it possible to make getopt a
> > builtin command in bash so that any script depends on it will be more
> > portable and faster?

I think it would make things less portable rather than more portable.
Among other things that would mean yet another implementation of
getopt that would almost certainly have some behavior difference.

How can the speed of getopt be significant?  It is called once for
effect and only three times total when testing portability.  If it is
called more often than this then something is misunderstood about it
should be used.

> > Why was getopts introduced in the first place
> > without the full feature of getopt?

AFAIK it was introduced into AT&T ksh way back before 1986.  I didn't
research this.  But that is where my memory recalls it without fact
checking.  But at the time back in the 1980's many things were added
as builtins to ksh.  Note that at the time it was added to ksh the
Unix getopt was not as featureful as the current one.  Comparing the
same era getopt to the same era getopts and they are much more
comparable.  Bash is as compatible as practical to other shells.
Therefore it is in Bash for compatibility.

Also while getopt has more features than getopt it is also true that
getopts has more features than getopt.  They are different features
and they don't overlap.  The builtin getopts is called in a loop.  The
external getopt is called once and then a shell loop using builtin
shell constructs is called in a loop to parse it.

> And using getopt in a script is atrociously stupid UNLESS you have TESTED
> that the getopt you are invoking is in fact the non-standard Linux one.

I think that is too harsh.  It is perfectly reasonable to use getopt
in portable shell scripts.  I have great respect for your deep
knowledge of the shell but I disagree that getopt should never be used
in shell scripts.

> The amount of code you would have to add to test this, in order to be
> sure that it is safe to use, is large enough that you would be better
> off simply writing a normal option processing loop using the standard
> tools instead.  (And it would run faster, too, because you wouldn't have
> to fork an external command... repeatedly... to process your options.)

Hmm...  It doesn't seem very onerous to me.

SHORTOPTS="d:qv"
LONGOPTS="dir:,dry-run,help,quiet,verbose,version"

if $(getopt -T >/dev/null 2>&1) ; [ $? = 4 ] ; then # New longopts getopt.
  OPTS=$(getopt -o $SHORTOPTS --long $LONGOPTS -n "$progname" -- "$@")
else # Old classic getopt.
  # Special handling for --help and --version on old getopt.
  case $1 in --help) print_help ; exit 0 ;; esac
  case $1 in --version) print_version ; exit 0 ;; esac
  OPTS=$(getopt $SHORTOPTS "$@")
fi

if [ $? -ne 0 ]; then
  echo "'$progname --help' for more information" 1>&2
  exit 1
fi

eval set -- "$OPTS"

And this is only if you care about using long options and care about
portability to older Unix versions without it.  And error handling.
Otherwise it it simply this.

SHORTOPTS="d:qv"
LONGOPTS="dir:,dry-run,help,quiet,verbose,version"
OPTS=$(getopt -o $SHORTOPTS --long $LONGOPTS -n "$progname" -- "$@")
eval set -- "$OPTS"

> If your program is so incredibly complex that you feel you need Linux
> getopt to handle its options, then perhaps you should rewrite it in a
> more advanced programming language than bash.

For complex data structures or other escalation of complexity I
completely agree with you.  Use a more powerful scripting language for
the program.

But option processing isn't very complicated.  Often a nice shell
script is needed and all of the now defacto standard option processing
is also expected.  It is perfectly portable and maintainable to write
a shell script that does robust option processing.  Using either
getopt or getopts.  They are simply different alternate styles of
accomplishing the same task.  I prefer getopt in order to implement
the full GNU style option processing.  It's fine.  Really!  :-)

Bob



reply via email to

[Prev in Thread] Current Thread [Next in Thread]