Subject: Re: This has GOT to be a bug in ksh...
To: NetBSD User's Discussion List <netbsd-users@netbsd.org>
From: Greg A. Woods <woods@weird.com>
List: netbsd-users
Date: 06/18/2002 14:27:50
[ On Tuesday, June 18, 2002 at 20:07:38 (+0700), Robert Elz wrote: ]
> Subject: Re: This has GOT to be a bug in ksh... 
>
> But when the echo in the loop is replaced by code that does some
> real work, it would be entirely reasonable for the script to contain
> something like
> 
> 	$verbose && echo "Processing $file"
> 
> which works just fine with any reasonable version of echo which actually
> implements an echo function, rather than being a badly named print.

You're apparently still looking for the simple little "echo" described
so eloquently by Kernighan and Pike.  Well, she's not so simple any
more, she's long grown up now, and the sensitive young youth really did
bash his head open against the shells on the shore.  What we now call
"echo" is a tool for producing prompts and messages in scripts that's
just sophisticated enough to be useful and not so overly complex that it
requires a multi-page document to describe it, with references to even
longer prerequisite knowledge.  Yes, it may indeed be a badly named
"print", but in the interests of moving forward while at the same time
not burning any bridges it's been deemed (by many and far more
experienced people than I -- I just happen to agree with their
reasoning) that this tool still go by the name "echo".  Why even back
when K&P penned their story (nearly two decades ago) the deed had
already long been done!  Why are you still longing after all these years
for something that really does not exist in the same form any more?


> With your definition of what echo should do, just how do you manage to
> handle things like that?

It's very easy, but it doesn't involve using "echo" or anything similar,
and it does require consideration of at least two important alternatives:

If your definition of "works" is to simply copy the exact characters of
the filename to the standard output, regardless of how they'll appear to
a human user looking at whatever device happens to be connected, then
all we need to do is get the contents of the variable containing the
filename written verbatim to some tool that'll copy it to stdout and of
course that's pretty easy to do with a Bourne-compatible shell:

for file in * ; do
	cat <<__END__
$file
__END__
done


If your definition of "works" is to print exactly the name of the file
then you've got other far more serious problems to deal with -- you'll
need to know the exact type of device you're writing to in order that
your program can (possibly dynamically) figure out how to represent the
characters making up the filename on the output device.  One generic
solution that doesn't require dynamic device-dependent adjustment is
to use "vis" (or maybe "cat -v") instead of "cat" as above:

for file in * ; do
	vis -cw <<__END__
$file
__END__
done


We can of course then jazz that up and make it more of a real-world
example, as with your example:

for file in * ; do
	if $verbose; then
		echo "Now processing:  \c"
		vis -ctl <<__END__
$file
__END__
		echo ""
	fi
	# now do something with the file....
	doit "$file"
done


Yes, it's ugly.  Yes it may be easier to use "printf":

for file in * ; do
	$verbose && printf "Processing: '%s'\n" "$file"
	doit "$file"
done


but then "printf" cannot yet do what "vis -ctl" can (though it wouldn't
be hard to fix -- something the opposite of '%b' is all that's really
needed, and really printf(3) needs such features too!)

-- 
								Greg A. Woods

+1 416 218-0098;  <gwoods@acm.org>;  <g.a.woods@ieee.org>;  <woods@robohack.ca>
Planix, Inc. <woods@planix.com>; VE3TCP; Secrets of the Weird <woods@weird.com>