lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) (12/27/90)
Well, it should have been easy, but everything I've tried has failed, so I'll go to the experts... (;-) What I've been trying to do is write a script whose semantics are sort of like the cp/mv/ln commands, in that the last argument is special. If it is a directory, I want to do something different that amounts to appending character strings to its name to give file name[s] within the directory; if it is an ordinary file, I just want to use its name. The problem is that I can't figure out any Bourne-shell expression that gives the last argument. In C-shell, it's easy (argv[$#]). But I need to write Bourne shell scripts. In fact, they need to be BSD bourne shell scripts rather that ATT Bourne shell scripts. The difference is probably significant here, because of the differences in the way these two Bourne shells handle variables. Actually, it'd be really nice to find a solution that is portable, but that may be just a dream. The obvious thing to try is some sort of expression combining $# with ${}, e.g. ${$#}. This gets a syntax error. The simpler $$# is valid, but it just gives the process id followed by a '#', not even close. I've also tried assigning $# to a variable and using that, but all I've managed to get is the number of the last arg, not its value. At the moment I've kludged the job by writing a program lastfld.c that just prints argv[argc-1]. But it seems incredibly stupid to have to pass all the args to a subprocess which throws away all but the last one. I mean, the shell knows which arg is which; why go to the expense of starting up a subprocess to learn something that the parent already knows? The pseudo-code I'd like to use is: if [ -d last-command-line-arg ] then ... fi Any ideas?
rouben@math9.math.umbc.edu (Rouben Rostamian) (12/27/90)
In article <18476@shlump.nac.dec.com> lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) writes: >What I've been trying to do is write a script whose semantics are sort of >like the cp/mv/ln commands, in that the last argument is special. If it >is a directory, I want to do something different that amounts to appending >character strings to its name to give file name[s] within the directory; >if it is an ordinary file, I just want to use its name. > >The problem is that I can't figure out any Bourne-shell expression that >gives the last argument. In C-shell, it's easy (argv[$#]). But I need >to write Bourne shell scripts. Here's what you need: #!/bin/sh eval lastarg=\${$#} ...etc... -- Rouben Rostamian Telephone: (301) 455-2458 Department of Mathematics and Statistics e-mail: University of Maryland Baltimore County bitnet: rostamian@umbc Baltimore, MD 21228, U.S.A. internet: rostamian@umbc3.umbc.edu
bob@wyse.wyse.com (Bob McGowen x4312 dept208) (12/27/90)
In article <18476@shlump.nac.dec.com> lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) writes: >Well, it should have been easy, but everything I've tried has failed, so >I'll go to the experts... (;-) > >What I've been trying to do is write a script whose semantics are sort of >like the cp/mv/ln commands, in that the last argument is special. If it >is a directory, I want to do something different that amounts to appending >character strings to its name to give file name[s] within the directory; >if it is an ordinary file, I just want to use its name. > >The problem is that I can't figure out any Bourne-shell expression that >gives the last argument. In C-shell, it's easy (argv[$#]). But I need >to write Bourne shell scripts. In fact, they need to be BSD bourne shell >scripts rather that ATT Bourne shell scripts. The difference is probably >significant here, because of the differences in the way these two Bourne As an aside, could you explain this comment? I have had minimal contact with BSD, but my experience does not seem to support this statement. >shells handle variables. Actually, it'd be really nice to find a solution >that is portable, but that may be just a dream. ---deleted discussion--- >Any ideas? Three solutions came to mind: 1) using eval; 2) using shift; 3) using a combined while loop/if statement with the shift. 1) eval echo this is the last argument \$$# This works because the shell evaluates the right $ with the # to give the last argument (not really, but see later), then re-reads the line with the value of this number following the first $, which it now sees as an unprotected character and gives the substituted arg that matches. Now for the "not really": this will only work for a list of args that is not bigger than nine. The tenth arg would result in output like: this is the last argument a0 where the a is arg 1 ($10 is the concatenation of $1 and 0). 2) shift `expr $# - 1` echo the last arg is $1 The Bourne shell on AT&T's SysV/386 and the Sun OS support a numeric argument to the shift. This number of args are shifted out of the list. So if there are ten args, expr gives nine for the shift, the last arg becomes $1. The problem here is that all the preceding args are thrown away. 3) while [ ! -z "$1" ] do if [ $# -eq 1 ] then last=$1 shift else rest="$rest $1" shift fi done Each argument is collected as encountered on the command line (except for the case where it contains white space -- "a b"; this is a little hard to handle with this type of structure because the "arguments" are parsed three times: once as $1, again in the if to construct the $rest and later whenever $rest is used). All except the last are collected into the variable rest, the last is in the variable last. You can now manipulate the parts as needed. For instance, to create a path name with the last arg as the first component: for item in $rest do echo $last/$item done I hope this slightly lengthy discussion helps. Bob McGowan (standard disclaimer, these are my own ...) Product Support, Wyse Technology, San Jose, CA ..!uunet!wyse!bob bob@wyse.com
jeff@onion.pdx.com (Jeff Beadles) (12/27/90)
In <18476@shlump.nac.dec.com> lan_csse@netrix.nac.dec.com writes: ... >The problem is that I can't figure out any Bourne-shell expression that >gives the last argument. ... >Any ideas? Well, there's nothing that I am aware of in /bin/sh that will ALWAYS allow this to work. The problem is that if you have more than 9 arguements, you have to shift them off to get to what you want. Here's one try that might be of use: #!/bin/sh if [ $# -gt 0 -a $# -lt 10 ] ; then LAST=`eval echo \\$$#` ## 1-9 == Great! elif [ $# -le 0 ] ; then LAST="NO_ARGS" ## 0 == Oops! None! else LAST="TOO_MANY_ARGS" ## >9 == Oops! Too many! fi echo "LAST= >$LAST<" exit 0 However, this is not all that swift. "foo a b c d e f g h i j k" won't work with this. The only other hope is to save off the arguements and loop until the end. This has the possibility of screwing up any special characters and/or white space though, and is generally not-so-hot. -Jeff -- Jeff Beadles jeff@onion.pdx.com
cpcahil@virtech.uucp (Conor P. Cahill) (12/27/90)
In article <18476@shlump.nac.dec.com> lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) writes: >The obvious thing to try is some sort of expression combining $# with ${}, >e.g. ${$#}. This gets a syntax error. The simpler $$# is valid, but it Try: eval \$$# -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
maart@cs.vu.nl (Maarten Litmaath) (12/28/90)
# How to get the last argument of a shell script reliably. # If you are sure the number of arguments is in [1-9], you can use this: # # eval last=\$$# # # The general (backquote) solution works for ANY number of arguments. # In POSIX-compatible shells this works for any $#: # # eval last=\${$#} set a b c d e f g h i j k l m -n # For example. case $# in 0) # So the user tried to be funny; let's give him a little surprise. exec kill -SYS $$ ;; [1-9]) eval last=\$$# ;; *) last=` n=$# set '' ${1+"$@"} shift $n echo -n "$1" ` esac echo "last=|$last|" -- _ d _\ _\ 2 ih -- Y = (c A . p + m c B) Y dt 0
davidsen@sixhub.UUCP (Wm E. Davidsen Jr) (12/31/90)
In article <1990Dec27.154917.14751@virtech.uucp> cpcahil@virtech.UUCP (Conor P. Cahill) writes: | In article <18476@shlump.nac.dec.com> lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) writes: | >The obvious thing to try is some sort of expression combining $# with ${}, | >e.g. ${$#}. This gets a syntax error. The simpler $$# is valid, but it | | Try: | eval \$$# With sh there is no valid way to do this, it breaks when $# > 9. With ksh the followinf is true: eval echo $# \$## # uses only one digit of $# eval echo $# \${$#} # works for all values Hope that clarifies it. I treid several shells, all flavors of sh seem to stop at $#>9 and need evaluation via shift. -- bill davidsen - davidsen@sixhub.uucp (uunet!crdgw1!sixhub!davidsen) sysop *IX BBS and Public Access UNIX moderator of comp.binaries.ibm.pc and 80386 mailing list "Stupidity, like virtue, is its own reward" -me
lvc@cbnews.att.com (Lawrence V. Cipriani) (01/01/91)
In article <18476@shlump.nac.dec.com>, lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) writes: > The pseudo-code I'd like to use is: > if [ -d last-command-line-arg ] > then > ... > fi If you don't need to have the last command line argument in a variable you can do this: if eval [ -d "\${${#}}" ] then ... fi -- Larry Cipriani, att!cbvox!lvc or lvc@cbvox.att.com "I just love the smell of gunpowder!" - Bugs Bunny
mercer@npdiss1.StPaul.NCR.COM (Dan Mercer) (01/02/91)
In article <1990Dec27.154917.14751@virtech.uucp> cpcahil@virtech.UUCP (Conor P. Cahill) writes: :In article <18476@shlump.nac.dec.com> lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) writes: :>The obvious thing to try is some sort of expression combining $# with ${}, :>e.g. ${$#}. This gets a syntax error. The simpler $$# is valid, but it : :Try: : eval \$$# : :-- :Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., :uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 : Sterling, VA 22170 Obviously this fails for $# > 9. So you need some form of shift, preferably forking and execing as few processes as possible (nice to avoid expr). You'd also like to preserve the current args. So try this: args="$@" # get arglist argno=$# # and number of current args export args argno last=`set -- spacer $args # set as args - add spacer to eliminate expr shift $argno # shift over echo $1` This works if args contains no args with embedded whitespace - if that is a possibility, then expr must be used. args="$@" export args argno last=` set -- spacer $args shift \`expr $# - 1\` echo $1` echo $last But this also fails if last arg may contain whitespace. Oh well! -- Dan Mercer NCR Network Products Division - Network Integration Services Reply-To: mercer@npdiss1.StPaul.NCR.COM (Dan Mercer) "MAN - the only one word oxymoron in the English Language"
martin@mwtech.UUCP (Martin Weitzel) (01/02/91)
In article <1990Dec27.060903.1604@onion.pdx.com> jeff@onion.pdx.com (Jeff Beadles) writes: >In <18476@shlump.nac.dec.com> lan_csse@netrix.nac.dec.com writes: >>The problem is that I can't figure out any Bourne-shell expression that >>gives the last argument. >... >>Any ideas? > >Well, there's nothing that I am aware of in /bin/sh that will ALWAYS allow >this to work. The problem is that if you have more than 9 arguements, you >have to shift them off to get to what you want. Not really. I have waited some time, but as Chris Torek seems to be in vacation I'll bite the bullet this time :-) [%]. What ALLWAYS works in the Bourne-Shell is this: for last do :; done Explanation: The for loop loops over all arguments of the current procedure, if you leave out the `in'-clause. Every argument is put into the variable you name after `for'. This leaves the last argument in last when the loop is through. You can also access the second last (third last, etc) argument if you extend this trick a little: for i do last3=$last2 last2=$last last=$i done And please DON'T use `for i in $*' instead of leaving the `in'-clause out! It's not the same - despite some UNIX books claim so!! (For the nit-pickers: `for i' is the same as `for i in ${1+"$@"}' i.e. you will never run into problems if there are no arguments or some arguments have embedded blanks.) %: Shouldn't this be in the FAQ-list or is it? (I've no recent copy available) -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
chet@odin.INS.CWRU.Edu (Chet Ramey) (01/03/91)
>>In fact, they need to be BSD bourne shell >>scripts rather that ATT Bourne shell scripts. The difference is probably >>significant here, because of the differences in the way these two Bourne > > As an aside, could you explain this comment? I have had minimal contact > with BSD, but my experience does not seem to support this statement. The BSD /bin/sh is the one from v7, with minimal changes for the 4.2 BSD signal semantics (restarted system calls, etc.) and # as a comment character. The AT&T /bin/sh changed drastically beginning with System V.2, and further changes appeared in System V.3. Here's a short list of what was added to the v7 sh for the System V.2 sh: shell functions and the `return' builtin redirection of input/output for builtins (e.g. `read x < /dev/tty') command hashing, `set -h', and the hash builtin test/[, echo, pwd, ulimit builtins exit status of a pipeline was defined to be the exit status of the last command set -a, set -f # as the comment character (this was put in at Berkeley and adopted by AT&T) colon form of parameter substitution to test for nullness of a variable CDPATH MAILCHECK, MAILPATH the use of `!' to negate a [] pattern for filename generation the `<<-' form of here-document redirection (strip leading tabs) set -- numeric parameter to the shift builtin the unset builtin (!) restricted shell mode There were a few changes between the System V.2 sh and the V.3 sh, in addition to bug fixes: the shell is now 8-bit clean (that is, the shell no longer implements quoting by turning on the 8th bit of characters) function arguments no longer overwrite the global set of positional parameters the getopts builtin The BSD /bin/sh, which is still pretty much the V7 /bin/sh, includes `login' as a builtin and allows `chdir' as a synonym for `cd'. The System V shell includes `newgrp' as a builtin. As of 4.3 BSD, the BSD sh accepts # as a comment only when non-interactive. Chet -- Chet Ramey ``I die, Horatio'' Network Services Group, Case Western Reserve University chet@ins.CWRU.Edu My opinions are just those, and mine alone.
bob@wyse.wyse.com (Bob McGowen x4312 dept208) (01/03/91)
In article <1991Jan2.174157.21530@usenet.ins.cwru.edu> chet@po.CWRU.Edu writes: >>>In fact, they need to be BSD bourne shell >>>scripts rather that ATT Bourne shell scripts. The difference is probably >>>significant here, because of the differences in the way these two Bourne >> >> As an aside, could you explain this comment? I have had minimal contact >> with BSD, but my experience does not seem to support this statement. > >The BSD /bin/sh is the one from v7, with minimal changes for the 4.2 BSD >signal semantics (restarted system calls, etc.) and # as a comment >character. The AT&T /bin/sh changed drastically beginning with System V.2, >and further changes appeared in System V.3. > >Here's a short list of what was added to the v7 sh for the System V.2 sh: ---description of differences deleted--- >accepts # as a comment only when non-interactive. > >Chet >-- Thanks for the list of differences. It will be useful, I'm sure!-) However, the original posters statement was that there were differences in how the versions of the shells handle "variables", which my experience seems to show is either the same or very nearly so, since all of the scripts I have written work with both BSD and AT&T sh's. So, even though the above list is very useful, the specific point of possible differences in how the shells handle parameters (command line arguments and variables) is still open. Any information on this particular point would be helpful. Thanks, Bob McGowan (standard disclaimer, these are my own ...) Product Support, Wyse Technology, San Jose, CA ..!uunet!wyse!bob bob@wyse.com
hansm@cs.kun.nl (Hans Mulder) (01/04/91)
In article <1991Jan2.174157.21530@usenet.ins.cwru.edu> chet@po.CWRU.Edu writes: >Here's a short list of what was added to the v7 sh for the System V.2 sh: [ stuff deleted ] >exit status of a pipeline was defined to be the exit status of the last command Nit-pick: Both the v7 and the SVR2 sh manuals mention that "the exit status of a pipeline is the exit status of the last command". The problem is the the word "last" is ambiguous. The v7 sh takes it to mean "last to terminate", SVR2 interprets it as "rightmost". Thus the pipeline "sleep 10 | false" would be considered successful by the v7 shell (since the sleep terminates last, and successfully), while the SVR2 sh considers it unsuccessful. I think the latter behaviour is more useful. For one thing, it makes "if foo | grep -s bar" work right 100% of the time. Happy New Year, Hans Mulder hansm@cs.kun.nl
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (01/04/91)
In article <2577@wn1.sci.kun.nl> hansm@cs.kun.nl (Hans Mulder) writes:
: I think the latter behaviour is more useful. For one thing, it makes
: "if foo | grep -s bar" work right 100% of the time.
Presuming, of course, that your grep actually returns a reasonable
exit status. Some don't, alas.
And the moral of the story? It's easier to port a shell than a shell script.
Larry Wall
lwall@jpl-devvax.jpl.nasa.gov
stuart@amc-gw.amc.com (Stuart Poulin) (01/05/91)
Of course if you know the last arg will never have white space and the command line wont have args like "=", you can use expr: Last=`expr "$*" : '.* \(.*\)' \| "$*"` -or- Use awk, it can handle a "=" by itself but still no white space. Last=`Last=`echo "$*" | awk '{ print $NF }'` -or- Something with sed or grep. I like the "for last do :; done" method - it's very clever and always works. Stuart Poulin DNS: stuart@amc.com Applications Engineer/System Administrator Applied Microsystems Corporation UUCP: amc-gw!stuart Redmond, Washington 98073 Dial: 800-ASK-4AMC,206-882-2000
allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (01/05/91)
As quoted from <1991Jan2.174157.21530@usenet.ins.cwru.edu> by chet@odin.INS.CWRU.Edu (Chet Ramey): +--------------- | Here's a short list of what was added to the v7 sh for the System V.2 sh: | | colon form of parameter substitution to test for nullness of a variable | set -- | numeric parameter to the shift builtin | restricted shell mode +--------------- Those four were in the System III /bin/sh. +--------------- | System V shell includes `newgrp' as a builtin. As of 4.3 BSD, the BSD sh | accepts # as a comment only when non-interactive. +--------------- Silliness. I disliked this in csh, I devoutly hope AT&T didn't pick it up for V.4 /bin/sh. Why should # be a comment only when noninteractive? There are valid reasons to use comments during interactive sessions --- *especially* under BSD, which has a working (read: pty-based) "script" command.... ++Brandon -- Me: Brandon S. Allbery VHF/UHF: KB8JRR on 220, 2m, 440 Internet: allbery@NCoast.ORG Packet: KB8JRR @ WA8BXN America OnLine: KB8JRR AMPR: KB8JRR.AmPR.ORG [44.70.4.88] uunet!usenet.ins.cwru.edu!ncoast!allbery Delphi: ALLBERY
jc@minya.UUCP (John Chambers) (01/05/91)
> What ALLWAYS works in the Bourne-Shell is this: > > for last do :; done Wow! A one-liner that works for more than 9 args! Of course, there's the question as to whether this loop is actually faster than starting a subprocess that just does puts(argv[artc-1]), but at least there's a way to do it that is portable. That comment isn't worth wasting the bandwidth, of course; my motive for this followup is a bit of bizarreness that I discovered while testing this command. The usual format of a for loop is 3 lines: for last do : done Usually when I want to collapse such vertical code into a horizontal format, I follow the rule "Replace the newlines with semicolons", and it works. For instance, if [ <test> ] then <stuff> else <stuff> fi reduces to if [ <test> ];then <stuff>;else <stuff>;fi which I can do in vi via a series of "Jr;" commands. With the above for-loop, this gives for last;do :;done which doesn't work. The shell gives a syntax error, complaining about an unexpected ';' in the line. Myself, I found this to be a somewhat unexpected error message. It appears my simple-minded algorithm for condensing code doesn't work in this case. So what's going on here? What the @#$^&#( is the shell's syntax that makes the semicolon not only unneeded, but illegal in this case? One of the real hassles I keep finding with /bin/sh (and /bin/csh is even worse ;-) is that the actual syntax regarding things like white space, newlines, and semicolons seems to be a secret. It often takes a lot of experimenting to find a way to get these syntax characters right. Is there any actual documentation on sh's syntax? Is it truly as ad-hoc as the above example implies? Is there perhaps some logical structure underlying it all that would explain why for last do :; done and for last do : done both work but for last;do :;done doesn't? -- Zippy-Says: Imagine ... a world without clothing folds, chiaroscuro, or marital difficulties ... Home: 1-617-484-6393 Work: 1-508-952-3274 Uucp: ...!{harvard.edu,ima.com,eddie.mit.edu,ora.com}!minya!jc (John Chambers) Uucp-map: minya adelie(DEAD)
Dan_Jacobson@ATT.COM (01/07/91)
>>>>> On 5 Jan 91 15:56:45 GMT, jc@minya.UUCP (John Chambers) said
among many other things that I was too lasy to go downstirs to get the
book to look up [it's cold down there]:
John> Is there any actual documentation on sh's syntax?
In the 4.3 BSD document set you'll find a syntax description in the sh
articles in [I think] the User's Supplementary Documents volume.
--
Dan_Jacobson@ATT.COM Naperville IL USA +1 708-979-6364
chet@odin.INS.CWRU.Edu (Chet Ramey) (01/08/91)
In article <DANJ1.91Jan6120607@cbnewse.ATT.COM> danj1@ihlpa.att.com writes: >John> Is there any actual documentation on sh's syntax? >In the 4.3 BSD document set you'll find a syntax description in the sh >articles in [I think] the User's Supplementary Documents volume. The article is ``An Introduction to the Unix Shell'', USD:3, by S. R. Bourne. There is a grammar in the appendix. Take it with a grain of salt, though; as described by that grammar, sh does not accept ``who | wc'' as a legal command. Chet -- Chet Ramey ``There's just no surf in Network Services Group Cleveland, U.S.A. ...'' Case Western Reserve University chet@ins.CWRU.Edu My opinions are just those, and mine alone.
allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (01/08/91)
As quoted from <443@minya.UUCP> by jc@minya.UUCP (John Chambers): +--------------- | as ad-hoc as the above example implies? Is there perhaps some logical | structure underlying it all that would explain why | for last do :; done | and | for last | do : | done | both work but | for last;do :;done | doesn't? +--------------- I suspect a /bin/sh bug. I just tried it on an ancient ksh and an almost-as- old [ ;-) ] Xenix; Xenix sh barfed, but ksh accepted it. I'll try it under System V 3.2 /bin/sh tomorrow. ++Brandon -- Me: Brandon S. Allbery VHF/UHF: KB8JRR on 220, 2m, 440 Internet: allbery@NCoast.ORG Packet: KB8JRR @ WA8BXN America OnLine: KB8JRR AMPR: KB8JRR.AmPR.ORG [44.70.4.88] uunet!usenet.ins.cwru.edu!ncoast!allbery Delphi: ALLBERY
Chuck.Phillips@FtCollins.NCR.COM (Chuck.Phillips) (01/14/91)
>>>>> On 5 Jan 91 15:56:45 GMT, jc@minya.UUCP (John Chambers) said:
John> With the above for-loop, this gives
John> for last;do :;done
John> which doesn't work. The shell gives a syntax error, complaining
John> about an unexpected ';' in the line. Myself, I found this to be a
John> somewhat unexpected error message. It appears my simple-minded
John> algorithm for condensing code doesn't work in this case.
John> So what's going on here? What the @#$^&#( is the shell's syntax that
John> makes the semicolon not only unneeded, but illegal in this case?
A little sh history: sh comments originally went from a ':' to the end of a
line. ('#'-style comments were added later.) The funny thing about ':'
comments is they get evaluated and have a return value, unlike '#' comments
which are merely whitespace.
For example:
: Arbitrary text here > foop
This "comment" wipes out the file foop, if it exists, then creates a null
file called "foop". (Wonder why they added '#' comments? ;^) The shell
does not attempt to execute a command called "Arbitrary", and the comment
has a return value of zero (a.k.a. success).
':' statements have other uses besides a filler with a return value of '0'
and an obscure way to create null files.
: ${VARIABLE=value}
Sets variable VARIABLE to "value" unless VARIABLE is already set. Lastly,
beginning a sh script with ":" instead of "#! /bin/sh" saves an unnecessary
fork and exec on some versions of UNIX. (Note to bash users: In bash,
scripts beginning with ":" are interpreted by bash while "#! /bin/sh"
scripts are, of course, executed by "/bin/sh".)
To answer your original question:
for last;do :;done
The ";done" part of the statement is a comment, which yields a syntax
error. (sh error messages are often misleading, IMHO.)
John> One of the real hassles I keep finding with /bin/sh (and /bin/csh is
John> even worse ;-) is that the actual syntax regarding things like white
John> space, newlines, and semicolons seems to be a secret.
Oh, that reminds me. You're not to repeat anything I've said. :-)
I agree that csh is worse, mostly due to its (mis)handling of newlines. I
still use csh interactively, but program in sh after being burned a few
times by csh's unexpected syntax exceptions and variations. (Just try
piping the result of one loop into another loop in csh without using a
temporary file, FIFO or multiple invocations of csh.)
#include <std/disclaimer.h>
Hope this helps,
--
Chuck Phillips MS440
NCR Microelectronics chuck.phillips%ftcollins.ncr.com
2001 Danfield Ct.
Ft. Collins, CO. 80525 ...uunet!ncrlnk!ncr-mpd!bach!chuckp