home *** CD-ROM | disk | FTP | other *** search
- From mipos3!intelca!oliveb!pyramid!decwrl!sun!pitstop!sundc!seismo!uunet!munnari!basser!john Thu Apr 14 18:00:20 PDT 1988
- Article 347 of comp.sources.misc:
- Path: td2cad!mipos3!intelca!oliveb!pyramid!decwrl!sun!pitstop!sundc!seismo!uunet!munnari!basser!john
- From: john@basser.cs.su.oz.AU (John Mackin)
- Newsgroups: comp.sources.misc
- Subject: v02i093: Autoloading shell scripts as functions
- Message-ID: <1226@basser.oz>
- Date: 12 Apr 88 21:41:16 GMT
- Sender: john@basser.oz
- Lines: 151
- Approved: john@basser.cs.su.oz.AU
-
- comp.sources.misc: Volume 2, Issue 93
- Submitted-By: John Mackin <john@basser.cs.su.oz.AU>
- Archive-Name: autoload
-
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # Wrapped by john on Wed Apr 13 07:08:49 EST 1988
- # Contents: README autoload which
-
- echo x - README
- sed 's/^@//' > "README" <<'@//E*O*F README//'
- @ Autoloading Shell Scripts as Functions
-
- @ Concept and Implementation by (in alphabetical order):
-
- @ John Mackin <john@basser.cs.su.oz.AU>
- @ Boyd Roberts <boyd@basser.cs.su.oz.AU>
-
-
- If you don't have a shell that supports functions, don't bother with
- this. If you do, well, we developed this under the Rob Pike (Eighth
- Edition) shell, but we tested it on System V (seems to work as long
- as you don't try to export any functions) and under ksh (seems like
- it might work, we aren't sure though). Caveat emptor, it's mainly the
- idea that matters, we're sure you can make it work on your implementation
- if you want to.
-
- Suppose you have a shell function that you don't often use, that must
- be a function and not a script (maybe it sets environment variables).
- Or just say you have some big functions that you would like to have
- around when you want them, but that don't clutter your environment
- when you're not using them (for those that can export functions, that
- is). Then this code is for you. Originally inspired by the Franz
- Lisp `autoload' mechanism, this allows you to write your functions
- as scripts, and have them autoloaded as functions into the calling
- shell the first time they are executed.
-
- For example, if $HOME/bin was in your path, and $HOME/bin/foo contained:
-
- @ #!/bin/sh
-
- @ echo This is foo.
-
- Then if you included our autoload functions in your .profile, along
- with a call to autoload:
-
- @ autoload foo
-
- foo would originally get a function definition that would cause its
- autoloading if it were ever used, and after it was first used it would
- be defined as:
-
- @ foo()
- @ {
- @ echo This is foo.
- @ }
-
- We've included a copy of `which' after Kernighan & Pike (`The UNIX
- Programming Environment') so that this can be 100% self-contained. Feel
- free to use a shell builtin instead if you have one that works (we
- do, almost...).
-
- One `gotcha' is that if you autoload a script that uses here documents
- (that is, `<<') you may be surprised by the result. It works on our
- shell, though; well, sort of. I have no idea what other shells will
- do with it.
-
- Another `gotcha' is that you shouldn't blindly autoload any script;
- rather, it requires a little bit of pre-planning. In particular,
- setting environment variables cuts both ways. What's great for
- a cutie that changes $TERM based on what kind of terminal your
- window is emulating is no fun at all if the script (and hence
- the function) changes PATH, or worse, IFS.
-
- Have fun!
-
- John Mackin, Basser Department of Computer Science,
- @ University of Sydney, Sydney, Australia
-
- john@basser.oz.AU (john%basser.oz.AU@UUNET.UU.NET)
- {uunet,mcvax,ukc,nttlab}!munnari!basser.oz!john
- @//E*O*F README//
- chmod u=rw,g=r,o=r README
- echo x - autoload
- sed 's/^@//' > "autoload" <<'@//E*O*F autoload//'
- autoload()
- {
- @ for i
- @ do
- @ eval "$i()
- @ {
- @ loadit $i &&
- @ $i "'"$@"'"
- @ }
- @ export $i
- @ "
- @ done
- }
-
- loadit()
- {
- @ if cmd=`which $1`
- @ then
- @ eval "$1()
- @ {
- @ `sed 's/\([^A-Za-z0-9_]*\)exec[ ]/\1/
- @ s/\([^A-Za-z0-9_]*\)exit[ ]/\1return /
- @ s/\([^A-Za-z0-9_]*\)exit$/\1return/
- @ s/\([^A-Za-z0-9_]*\)trap[ ]/\1: /' $cmd`
- @ }
- @ "
- @ else
- @ echo $1: not found >&2
- @ return 1
- @ fi
- }
-
- export autoload loadit
- @//E*O*F autoload//
- chmod u=rw,g=r,o=r autoload
- echo x - which
- sed 's/^@//' > "which" <<'@//E*O*F which//'
- # which - which command will execute?
-
- oldpath=$PATH
- PATH=/bin:/usr/bin
-
- case $# in
-
- @ 1) ;;
- @ *) echo usage: `basename $0` command-name >&2; exit 2 ;;
-
- esac
-
- for i in `echo $oldpath | sed 's/^:/.:/
- @ s/::/:.:/g
- @ s/:$/:./
- @ s/:/ /g'`
- do
- @ if test -f $i/$1
- @ then
- @ echo $i/$1
- @ exit 0
- @ fi
- done
-
- exit 1
- @//E*O*F which//
- chmod u=rwx,g=rx,o=rx which
- exit 0
-
-
-