home *** CD-ROM | disk | FTP | other *** search
- From: forsyth%minster.york.ac.uk@NSFNET-RELAY.AC.UK
-
- In response to a message from Maarten Litmaath about a
- problem with aliases, Chet Ramey gave the example of an alias
- `remote' written so that `remote x ls -l /bin/*' will pass
- its arguments to a remote machine x for evaluation. A similar
- `remote' function would not work, since its arguments would be
- expanded by the shell before calling the function.
-
- Here is a different approach.
-
- First, some background. A shell function is defined as follows
-
- myecho(){
- echo all mine: $*
- }
- cfiles(){
- echo *.c
- }
-
- Functions are used just like any other command:
-
- $ myecho a b c
- all mine: a b c
- $ myecho d e
- all mine: d e
- $ cfiles
- clipper.c sparc.c vax.c
- $ (cd elsewhere; cfiles)
- a.c b.c d.c
- $ myecho d e f >frog
-
- (note: perhaps Posix sh like ksh insists on having a clumsy and unnecessary
- `function' keyword before myecho() and cfiles().) The key point for
- this discussion is that the body of the function is evaluated only when
- the function is called. This applies in particular to macro calls like $* and
- file name expansion like *.c .
-
- Now, assume for the moment that the shell can somehow export functions,
- as in the 9th Edition (even if you think that this is `inefficient').
-
- With exported functions, the shell might treat
-
- command {A} ... {B} # where A and B are shell statement lists
-
- as (roughly) equivalent to
- sh$$-1(){A}
- sh$$-2(){B}
- export sh$$-1 sh$$-2
- command sh$$-1 ... sh$$-2
- unset sh$$-1 sh$$-2
-
- Why bother?
-
- time {ls | c} # time a pipeline without building time into sh
- rsh xxx {echo *.c} # does the *.c expansion on the remote system
- rsh xxx {ls -l /bin/*} # ramey's example, revisited: remote expansion
- rsh xxx ls -l /bin/* # no function: local expansion
- nohup {foggy | weather&}
- nice {refer|grap|pic|eqn|troff >X}&
- overwrite frog {tr A-Z a-z|sed 's/pepper/salt/'}
- echo {echo stuff and nonsense} # fairly useless result
-
- (note that i also assume that ; is no longer required before } for the shell
- to see it)
-
- The principle is the same as putting file name expansion into sh:
- the shell provides a general transformation for other commands,
- in this case, commands like rsh, time, and nohup that act on other commands.
- Of course, sh -c command can be (and is) used instead,
- but the quoting can become a nightmare (``Kernighan's Lemma can really bite.'')
-
- This approach also solves an old problem with `find':
- the {} syntax is unique to find, and it isn't general enough.
- For instance,
-
- find x -exec echo hello/{} \;
-
- has disappointing results on most systems.
-
- Suppose that find instead simply puts the current file name in the
- environment as $FILE using putenv. This would allow
-
- find x -exec mv '$FILE' /n/sniffle/'$FILE' \;
-
- and other more complicated things that are impossible with {}.
- The quoting is as much of a nuisance here, though, as it was with rsh.
-
- But now, combine the two ideas:
-
- find x -exec { mv $FILE /n/sniffle/$FILE && echo $FILE } \;
- find x -exec { chown fred,staff $FILE } \;
- find x -exec { basename $FILE .c } \;
- find x -exec { ls -l `resuffix $FILE .c .o` } \;
-
- I claim this is easier to document, explain, and understand,
- because it composes general operations that are not peculiar to find.
- (The \; could in principle be eliminated if -exec always took a {...} command,
- but in practice this could not sensibly be changed now.)
-
- All this requires that execvp look for exported functions, but then, it
- probably ought to anyhow, otherwise such functions cannot be used
- from commands other than sh.
-
- I think the basic problem with sh, alias, etc. is that
- people try to use macro processing as a sleazy substitute for things such as
- first-class procedures. Even so, I think one could make useful
- improvements without adding too many new warts,
- and as with find, time, nice, rsh, etc., a few old ones can be removed.
- (In a later note, I shall suggest why I think it might be pointless
- to put too much effort -- especially standardisation effort -- into such
- changes.)
-
-
- Volume-Number: Volume 19, Number 29
-
-