From owner-freebsd-questions Sun May 14 6: 9:43 2000 Delivered-To: freebsd-questions@freebsd.org Received: from praseodumium.btinternet.com (praseodumium.btinternet.com [194.73.73.82]) by hub.freebsd.org (Postfix) with ESMTP id 3FD0837B583 for ; Sun, 14 May 2000 06:09:30 -0700 (PDT) (envelope-from mark@ukug.uk.freebsd.org) Received: from [213.1.157.136] (helo=parish.my.domain) by gadolinium with esmtp (Exim 2.05 #1) id 12qvKd-0004Nd-00; Sun, 14 May 2000 11:09:08 +0100 Received: (from mark@localhost) by parish.my.domain (8.9.3/8.9.3) id LAA00943; Sun, 14 May 2000 11:09:00 +0100 (BST) (envelope-from mark) Date: Sun, 14 May 2000 11:09:00 +0100 From: Mark Ovens To: cjclark@home.com Cc: Erik Trulsson , questions@freebsd.org Subject: Re: getopt(1) or getopts(1)? Message-ID: <20000514110900.B232@parish> References: <20000511231319.C1522@parish> <20000512084656.A1146@student.csd.uu.se> <20000512183403.A233@parish> <20000513013931.C39310@cc942873-a.ewndsr1.nj.home.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 1.0.1i In-Reply-To: <20000513013931.C39310@cc942873-a.ewndsr1.nj.home.com>; from cjc@cc942873-a.ewndsr1.nj.home.com on Sat, May 13, 2000 at 01:39:31AM -0400 Organization: Total lack of Sender: owner-freebsd-questions@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Sat, May 13, 2000 at 01:39:31AM -0400, Crist J. Clark wrote: > On Fri, May 12, 2000 at 06:34:03PM +0100, Mark Ovens wrote: > > On Fri, May 12, 2000 at 08:46:56AM +0200, Erik Trulsson wrote: > > > On Thu, May 11, 2000 at 11:13:19PM +0100, Mark Ovens wrote: > > > > Can someone clarify getopt(1) and getopts(1)? According to sh(1): > > > > > > > > getopts optstring var > > > > The POSIX getopts command. The getopts command deprecates the > > > > older getopt(1) command..... > > > > > > > > but there is no manpage for getopts(1), only getopt(1). The latter > > > > includes some sample code which works fine, however if I change > > > > ``getopt'' to ``getopts'' in this code I get: > > > > > > > > parish:/usr/marko{89}% ./foobar -b > > > > getopts: -b: bad variable name > > > > Usage: ... > > > > parish:/usr/marko{90}% > > > > > > > > Since getopt(1) is deprecated it would be better to use getopts(1). > > > > Can anyone explain the above error, or point me to some documentation > > > > for getopts(1)? > > > > > > > > > > On my system (4.0-stable) there is a manpage for getopts(1). It just a link > > > to buiiltin(1) which says that it is a builtin command in sh(1). > > > > Same here (I'm also on 4-stable). I hadn't spotted that it is a copy > > of (not a link to) builtin(1). > > It is a link, hardlink. > > % cd /usr/share/man/man1 > % ls -li getopts.1.gz builtin.1.gz getopt.1.gz > 508294 -r--r--r-- 71 root wheel 2407 Mar 25 03:08 builtin.1.gz > 508336 -r--r--r-- 1 root wheel 1649 Mar 25 03:10 getopt.1.gz > 508294 -r--r--r-- 71 root wheel 2407 Mar 25 03:08 getopts.1.gz > Oops! > > > > The manpage for sh(1) has the following to say about getopts: > > > > > > getopts optstring var > > > The POSIX getopts command. The getopts command deprecates the > > > older getopt(1) command. The first argument should be a series > > > of letters, each possibly followed by a colon which indicates > > > that the option takes an argument. The specified variable is set > > > to the parsed option. The index of the next argument is placed > > > into the shell variable OPTIND. If an option takes an argument, > > > it is placed into the shell variable OPTARG. If an invalid option > > > is encountered, var is set to `?''. It returns a false value (1) > > > when it encounters the end of the options. > > > > > > > > > > The first couple of lines of which I quoted in my original post so, > > yes, I have read it. However it reads as though the syntax is the same > > as getopt(1) (at least to me it does). So the question remains; why > > does the sample code in getopt(1) not work if I change ``getopt'' to > > ``getopts'' in the first line? > > It really is nothing like getopt(1). Not sure where it says anything > there that would lead one to believe that. > Yes, when I read it slowly several times I realized that :) > > I'm quite happy to RTFM, if only I could find a FM to R :) > > But this is a very good point. I can't find the FM, but for some > reason, I know how to use this... It works more like getopt(3); maybe > that's why it feels familiar. > > To get about the same functionality you see in the getopt(1) manpage, > you would have something like, > > while getopts abo: OPT; do > case $OPT in > a|b) > echo flag $OPT set; sflags="${OPT#-}$sflags" > ;; > o) > echo oarg is "'"$OPTARG"'"; oarg="$OPTARG" > ;; > *) > echo ERROR > exit 2 > esac > done > echo single-char flags: "'"$sflags"'" > echo oarg is "'"$oarg"'" > > getopts cycles through the argument list on its own. No need to > shift. It places the current option (the single letter) in the var > specified. The argument of the option, if it takes one, is in > OPTARG. Your current position on the command line is stored in OPTIND > (and is started at the first argument if OPTIND is unset). > I'd almost got there, except I didn't know that shift wasn't needed. > Almost makes life too easy, huh? Almost. It does seem somewhat lacking in the error handling dept. though. Using the example code above, if you do: # foobar -o -a -b then getopts(1) thinks that ``-a'' is the argument to ``-o''. Also, if it encounters an error such as an illegal option, or a missing argument then getopts(1) prints it's own error but sets $OPT to ``?'' which makes it difficult to generate your own error message, so instead of: # foobar -a -b -o No arg for -o option # you could output "-o requires a valid path as an argument" which would be easy if $OPT was set to ``o'' as you could test for $OPTARG = "" in the o case. OK, you could probably do it by keeping track of $OPTIND, but that points to the *next* option and if the error occurs on the last option it is set to 1, so you need to track the previous value of $OPTIND. Thanks for your help. > -- > Crist J. Clark cjclark@home.com > > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-questions" in the body of the message -- ...and on the eighth day God created UNIX ________________________________________________________________ FreeBSD - The Power To Serve http://www.freebsd.org My Webpage http://ukug.uk.freebsd.org/~mark/ mailto:mark@ukug.uk.freebsd.org http://www.radan.com To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message