home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / std_unix / volume.19 / text0028.txt < prev    next >
Encoding:
Internet Message Format  |  1990-05-17  |  3.9 KB

  1. From: forsyth%minster.york.ac.uk@NSFNET-RELAY.AC.UK
  2.  
  3. In response to a message from Maarten Litmaath about a
  4. problem with aliases, Chet Ramey gave the example of an alias
  5. `remote' written so that `remote x ls -l /bin/*' will pass
  6. its arguments to a remote machine x for evaluation.  A similar
  7. `remote' function would not work, since its arguments would be
  8. expanded by the shell before calling the function.
  9.  
  10. Here is a different approach.
  11.  
  12. First, some background.  A shell function is defined as follows
  13.  
  14.     myecho(){
  15.         echo all mine: $*
  16.     }
  17.     cfiles(){
  18.         echo *.c
  19.     }
  20.  
  21. Functions are used just like any other command:
  22.  
  23.     $ myecho a b c
  24.     all mine: a b c
  25.     $ myecho d e
  26.     all mine: d e
  27.     $ cfiles
  28.     clipper.c sparc.c vax.c
  29.     $ (cd elsewhere; cfiles)
  30.     a.c b.c d.c
  31.     $ myecho d e f >frog
  32.  
  33. (note: perhaps Posix sh like ksh insists on having a clumsy and unnecessary
  34. `function' keyword before myecho() and cfiles().)  The key point for
  35. this discussion is that the body of the function is evaluated only when
  36. the function is called.  This applies in particular to macro calls like $* and
  37. file name expansion like *.c .
  38.  
  39. Now, assume for the moment that the shell can somehow export functions,
  40. as in the 9th Edition (even if you think that this is `inefficient').
  41.  
  42. With exported functions, the shell might treat
  43.  
  44.     command {A} ... {B}    # where A and B are shell statement lists
  45.  
  46. as (roughly) equivalent to
  47.     sh$$-1(){A}
  48.     sh$$-2(){B}
  49.     export sh$$-1 sh$$-2
  50.     command sh$$-1 ... sh$$-2
  51.     unset sh$$-1 sh$$-2
  52.  
  53. Why bother?
  54.  
  55.     time {ls | c}        # time a pipeline without building time into sh
  56.     rsh xxx {echo *.c}    # does the *.c expansion on the remote system
  57.     rsh xxx {ls -l /bin/*}    # ramey's example, revisited: remote expansion
  58.     rsh xxx ls -l /bin/*    # no function: local expansion
  59.     nohup {foggy | weather&}
  60.     nice {refer|grap|pic|eqn|troff >X}&
  61.     overwrite frog {tr A-Z a-z|sed 's/pepper/salt/'}
  62.     echo {echo stuff and nonsense}    # fairly useless result
  63.  
  64. (note that i also assume that ; is no longer required before } for the shell
  65. to see it)
  66.  
  67. The principle is the same as putting file name expansion into sh:
  68. the shell provides a general transformation for other commands,
  69. in this case, commands like rsh, time, and nohup that act on other commands.
  70. Of course, sh -c command can be (and is) used instead,
  71. but the quoting can become a nightmare (``Kernighan's Lemma can really bite.'')
  72.  
  73. This approach also solves an old problem with `find':
  74. the {} syntax is unique to find, and it isn't general enough.
  75. For instance,
  76.  
  77.     find x -exec echo hello/{} \;
  78.  
  79. has disappointing results on most systems.
  80.  
  81. Suppose that find instead simply puts the current file name in the
  82. environment as $FILE using putenv.  This would allow
  83.  
  84.     find x -exec mv '$FILE' /n/sniffle/'$FILE' \;
  85.  
  86. and other more complicated things that are impossible with {}.
  87. The quoting is as much of a nuisance here, though, as it was with rsh.
  88.  
  89. But now, combine the two ideas:
  90.  
  91.     find x -exec { mv $FILE /n/sniffle/$FILE && echo $FILE } \;
  92.     find x -exec { chown fred,staff $FILE } \;
  93.     find x -exec { basename $FILE .c } \;
  94.     find x -exec { ls -l `resuffix $FILE .c .o` } \;
  95.  
  96. I claim this is easier to document, explain, and understand,
  97. because it composes general operations that are not peculiar to find.
  98. (The \; could in principle be eliminated if -exec always took a {...} command,
  99. but in practice this could not sensibly be changed now.)
  100.  
  101. All this requires that execvp look for exported functions, but then, it
  102. probably ought to anyhow, otherwise such functions cannot be used
  103. from commands other than sh.
  104.  
  105. I think the basic problem with sh, alias, etc. is that
  106. people try to use macro processing as a sleazy substitute for things such as
  107. first-class procedures.  Even so, I think one could make useful
  108. improvements without adding too many new warts,
  109. and as with find, time, nice, rsh, etc., a few old ones can be removed.
  110. (In a later note, I shall suggest why I think it might be pointless
  111. to put too much effort -- especially standardisation effort -- into such
  112. changes.)
  113.  
  114.  
  115. Volume-Number: Volume 19, Number 29
  116.  
  117.