home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.unix
- From: mzraly@ra.cs.umb.edu (Michael S. Zraly)
- Subject: v26i298: rmgetopts - remove getopts(1) from shell scripts, Part01/01
- Sender: unix-sources-moderator@gw.home.vix.com
- Approved: vixie@gw.home.vix.com
-
- Submitted-By: mzraly@ra.cs.umb.edu (Michael S. Zraly)
- Posting-Number: Volume 26, Issue 298
- Archive-Name: rmgetopts/part01
-
- The following program reads a shell script that uses getopts(1) to
- parse command line options and writes a new shell script that parses
- command line options without using getopts.
-
- This program was written in response to questions I have received from
- people wanting to use sftp (comp.sources.unix, volume 26) who don't
- have geopts built into their shell and don't have access to shells that
- do (e.g. ksh, bash).
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: MANIFEST Makefile README rmgetopts rmgetopts.1
- # Wrapped by mzraly@ra.cs.umb.edu on Fri Jul 16 06:00:50 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(251 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1
- X Makefile 1
- X README 1
- X rmgetopts 1
- X rmgetopts.1 1
- END_OF_FILE
- if test 251 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(609 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# rmgetopts Makefile
- X# Michael S Zraly
- X# mzraly@cs.umb.edu
- X# 16 July 1993
- X
- XPROG= rmgetopts
- X
- XBIN= /usr/local/bin
- XMAN= /usr/local/man
- X
- XFILES= Makefile README $(PROG) $(PROG).1
- X
- Xall: $(PROG).man $(PROG).1 $(PROG)
- X
- Xinstall: all
- X cp $(PROG) $(BIN) && chmod 755 $(BIN)/$(PROG)
- X cp $(PROG).1 $(MAN)/man1/$(PROG).1 && chmod 644 $(MAN)/man1/$(PROG).1
- X cp $(PROG).man $(MAN)/cat1/$(PROG).1 && chmod 644 $(MAN)/cat1/$(PROG).1
- X
- Xclean:
- X rm -f $(PROG).man $(PROG).tar.Z
- X
- X$(PROG).man: $(PROG).1
- X nroff -man $(PROG).1 > $(PROG).man
- X
- Xdist: $(PROG).tar.Z
- X
- X$(PROG).tar.Z: $(FILES)
- X tar cvf - $(FILES) | compress > $(PROG).tar.Z
- END_OF_FILE
- if test 609 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1030 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- Xrmgetopts README
- XMichael S Zraly
- Xmzraly@cs.umb.edu
- X16 July 1993
- X
- X
- XDESCRIPTION
- X
- XRmgetopts is a shell script that read a shell script that uses getopts
- Xto parse ocmmand line options and converts it into a script that does
- Xnot. The resulting script will still parse command line options with
- Xthe same syntax, but will be slightly more portable (albeit slower).
- X
- XINSTALLATION
- X
- XType "make install". The only "compiling" necessary is the formatting
- Xof the manual page; "make install" merely formats the manual page with
- Xnroff(1) and copies the manual pages and shell script into the
- Xappropriate directories. You'll have to update the whatis(1) database
- Xby hand, though, since there are too many variations for me to worry
- Xabout.
- X
- XBUG REPORTS
- X
- XSend them (and fixes, if you have them) to me at:
- X
- X mzraly@cs.umb.edu
- X
- XHISTORY
- X
- XI rewrote rmgetopts in response to the mail I got after posting sftp,
- Xwhich uses getopts, to comp.sources.unix. I had not realized at the
- Xtime that getopts was a shell built-in and that so few people had it.
- X
- END_OF_FILE
- if test 1030 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'rmgetopts' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rmgetopts'\"
- else
- echo shar: Extracting \"'rmgetopts'\" \(2531 characters\)
- sed "s/^X//" >'rmgetopts' <<'END_OF_FILE'
- X#!/bin/sh
- X#
- X# rmgetopts -- Replace option-parsing in shell script using getopts
- X# with more portable (but less efficient) hand-coded
- X# version.
- X#
- X# NOTE: rmgetopts expects its input to have the form
- X#
- X# ... random shell code ...
- X# while getopts optstr var
- X# do
- X# ... more shell code ...
- X# done
- X# shift `expr $OPTIND - 1`
- X# ... still more shell code ...
- X#
- X# In particular:
- X#
- X# (1) 'while getopts optstr var; do' is NOT allowed, at
- X# least not yet. The 'do' must follow the 'while'
- X# on a line by itself.
- X#
- X# (2) For now, whitespace consists solely of blank spaces
- X# (i.e. no tabs)
- X#
- X# (3) No whitespace of any sort may precede any of the
- X# 'while', 'do', 'done' or 'shift' lines.
- X#
- X# (4) No comments may follow any of the 'while', 'do',
- X# 'done', or 'shift' lines.
- X#
- X# (5) No restriction is made on the amount of whitespace
- X# used to separate individual tokens on any line.
- X# Trailing whitespace is allowed, but discouraged.
- X#
- X# Michael S Zraly
- X# mzraly@cs.umb.edu
- X# 16 July 1993
- X
- Xprog=`basename $0`
- Xusage='[file]'
- X
- XUSAGE="usage: $prog $usage"
- X
- X# determine value of $infile
- Xinfile=/tmp/rXmXg.??
- Xtrap 'rm -f $infile' 0 1 2 15
- X
- X# create $infile
- Xcase "$#" in
- X0) cat > $infile
- X ;;
- X1) cp $1 $infile
- X shift
- X ;;
- X*) echo $USAGE 1>&2
- X exit 1
- X ;;
- Xesac
- X
- X# make sure $infile contains calls to getopts...
- Xcase `grep -c '^while *getopts' $infile` in
- X0) echo $prog: cannot find getopts in input 1>&2
- X exit 1
- X ;;
- Xesac
- X
- X# edit $infile
- Xed - $infile <<'EOF' >/dev/null
- X/^while *getopts/
- Xs/while *getopts */OPTSTR=/
- Xs/ */\
- X/
- Xs/.*/\
- X &=$OPTOPT/
- X+1s/^do$//
- X?OPTSTR=?a
- Xwhile test "$#" -gt 0
- Xdo
- X case "$1" in
- X -|[!-]*) break;; # break from while loop
- X --) shift; break;; # break from while loop
- X esac
- X
- X OPTPOS=2
- X OPTOPT=`echo x$1 | colrm 1 $OPTPOS | colrm 2` # x$1 to avoid -n
- X
- X while test -n "$OPTOPT"
- X do
- X # if not legal arg, set OPTOPT to ?
- X case "`echo $OPTSTR | grep -c -e $OPTOPT`" in
- X 0) echo $prog: illegal option -- $OPTOPT 1>&2
- X OPTOPT='?';;
- X esac
- X
- X # set OPTARG appropriately
- X case "`echo $OPTSTR | grep -c -e $OPTOPT:`" in
- X 1) OPTPOS=`expr $OPTPOS + 1`
- X OPTARG=`echo x$1 | colrm 1 $OPTPOS`
- X case "$OPTARG" in
- X "") shift; OPTARG=$1;;
- X esac
- X OPTPOS=32766 # terminate this arg
- X ;;
- X *) OPTARG=;;
- X esac
- X.
- X+1,/^done *$/-1s/^/ /
- X/^done *$/d
- X/^shift *`expr *$OPTIND *- *1`/d
- Xi
- X # move on to next char in this arg
- X OPTPOS=`expr $OPTPOS + 1`
- X OPTOPT=`echo x$1 | colrm 1 $OPTPOS | colrm 2`
- X done
- X shift
- Xdone
- X.
- Xw
- Xq
- XEOF
- X
- X# print $infile (trap 0 should remove it)
- Xcat $infile
- X
- END_OF_FILE
- if test 2531 -ne `wc -c <'rmgetopts'`; then
- echo shar: \"'rmgetopts'\" unpacked with wrong size!
- fi
- chmod +x 'rmgetopts'
- # end of 'rmgetopts'
- fi
- if test -f 'rmgetopts.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rmgetopts.1'\"
- else
- echo shar: Extracting \"'rmgetopts.1'\" \(1250 characters\)
- sed "s/^X//" >'rmgetopts.1' <<'END_OF_FILE'
- X.\" rmgetopts manual-page
- X.\" Michael S Zraly
- X.\" mzraly@cs.umb.edu
- X.\" 16 July 1993
- X.\"
- X.TH RMGETOPTS 1 "July 16, 1993"
- X.SH NAME
- Xrmgetopts \- remove getopts processing from shell script
- X.SH SYNOPSIS
- X.B rmgetopts
- X[
- X.I file
- X]
- X.SH DESCRIPTION
- X.LP
- X.I rmgetopts
- Xreads a shell script that uses
- X.IR getopts (1)
- Xto process command options and converts it into one that does not.
- XInput
- X.B must
- Xhave the following form:
- X.LP
- X.RS
- X.nf
- X\&... random shell code ...
- X\&while getopts optstr var
- X\&do
- X\& ... more shell code ...
- X\&done
- X\&shift `expr $OPTIND - 1`
- X\&... still more shell code ...
- X.fi
- X.RE
- X.LP
- X.I rmgetopts
- Xis a ``dumb'' program that knows next to nothing about shell syntax;
- Xthe following restriction must be observed for it to work properly.
- X.IP \(bu
- XThe
- X.I do
- Xmust follow the
- X.I while
- Xon a separate line.
- X.IP \(bu
- XNo trailing comments are allowed on any of the
- X.IR while ,
- X.IR do ,
- X.IR done ,
- Xor
- X.I shift
- Xlines.
- X.IP \(bu
- XNone of the
- X.IR while ,
- X.IR do ,
- X.IR done ,
- Xor
- X.I shift
- Xlines may have whitespace preceding the first keyword.
- XAll lines in between the
- X.I do
- Xand
- X.I done
- Xlines ought to be indented.
- X.SH "SEE ALSO"
- X.IR getopts (1),
- X.IR sh (1).
- X.SH BUGS
- XThe resulting code process options rather slowly.
- X.SH AUTHOR
- XMichael S Zraly (mzraly@cs.umb.edu)
- END_OF_FILE
- if test 1250 -ne `wc -c <'rmgetopts.1'`; then
- echo shar: \"'rmgetopts.1'\" unpacked with wrong size!
- fi
- # end of 'rmgetopts.1'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-