echo (was $@ vs. $*)

Karl Heuer karl at haddock.UUCP
Thu Dec 25 04:30:20 AEST 1986


[This article will undoubtedly provoke a dozen identical postings of McIlroy's
humorous discussion of "echo", from Kernighan & Pike.  Please don't.]

In article <585 at mcgill-vision.UUCP> mcgill-vision!mouse (der Mouse) writes:
>In article <198 at haddock.UUCP>, karl at haddock.UUCP (Karl Heuer) writes:
>> The three major branches [of UNIX] (Research, USG, and Berkeley) have
>> distinct versions of echo!  ...
>> Btw, the V8 echo is the best of the lot; I hope the others adopt it.
>
>What are the differences?  Why do you feel V8 echo is best?

Berkeley echo is the same as Research V7.  It knows one flag ("-n", suppress
newline); anything else is echoed literally.  The only thing that's hard to
echo is a literal "-n" including newline.

USG echo (SysIII, SysV) doesn't expect any flags, but interprets backslash
escapes similar to C (except that they botched backslash-octal-digits, and
they added "\c" to suppress the newline).  This is a bad implementation of a
good idea.  (It's nice to be able to manipulate control characters without
having to embed them literally in the shell script, but it would've been more
useful to have it somehow built into the shell rather than each individual
program (echo, tr, stty, etc.).*)  The problem with this approach is that it
is now difficult to use echo to echo things!  Shell scripts that try to echo
variables into pipes (echo "$1" | sed ...) can have unexpected results.

Research V8 echo has the backslash escape feature, but they made it an option
which is off by default ("-e" enables it).  They also implemented backslash-
-octal-digits correctly (the same notation as in C), and they kept the -n flag
(so "echo -n foo" and "echo -e 'foo\c'" are equivalent).  One thing they might
have overlooked (I don't have a man page or a V8 system available; this is
from memory) is a way to forcibly terminate option scanning.  (With the USG
function getopt(), this is automatically provided via "--".  This notation is
probably as good as any.)  If this option is/were included, then one can/could
be sure of echoing something exactly by using `echo -- "$1"'.  This would also
allow for future additions**, e.g. an option to echo multiple arguments on
separate lines, without breaking existing scripts (provided they use "--").

Karl W. Z. Heuer (ima!haddock!karl or karl at haddock.isc.com), The Walking Lint
*I know "echo" is a builtin in ksh and SVR2 sh.  That's irrelevant, since it's
semantically identical to /bin/echo.  I'm talking about a feature that would
make `echo "$TERMCAP"' work literally (in spite of backslashes contained in
the variable) while `echo "\n"' (or some other notation) would pass a newline
in argv[1].  Now, backslash is already recognized inside double quotes, and so
it should be safe to add this as written; unfortunately, many shell scripts
depend on the current behavior and use a single backslash (instead of two)
when a real backslash is intended.  Perhaps "$\n" would be a safe notation?

**I dislike creeping featurism (Berkeley cat(1) is the classical example), but
`for i do echo "$i"; done' is annoying, ugly, and slow (compared to the
desired `echo -m "$@"').  Anyway, why isn't this the default behavior?  What
good are those embedded spaces on output, except for the benefit of people too
lazy to enclose a sentence in quotes?



More information about the Comp.unix.questions mailing list