Subject: Re: This has GOT to be a bug in ksh...
To: ali \(Anders Lindgren\) <dat94ali@ludat.lth.se>
From: Greg A. Woods <woods@weird.com>
List: netbsd-users
Date: 06/16/2002 11:12:59
[ On Sunday, June 16, 2002 at 15:23:05 (+0200), ali \(Anders Lindgren\) wrote: ]
> Subject: This has GOT to be a bug in ksh...
>
> $ for f in "Berra äter ost" "Lisa visar rattarna" ; do echo $f ; done
> "Berra äter ost"
> "Lisa visar rattarna"
> $
> 
> ok, great. So it *should* work. So let's do it on files then! Ergo:
> 
> $ touch "Berra äter ost" "Lisa visar rattarna"
> $ for f in `find . -type f | sed -e 's/\(.*\)/"\1"/'` ; do echo $f ; done
> "./Berra
> äter
> ost"
> "./Lisa
> visar
> rattarna"
> $

The quotes are only supposed to be necessary in the first case, not the
second.  The second should be written just as:

	$ for file in $(find . -type f -print) ; do echo $file ; done

Unfortunately that doesn't work.  My de-caffeinated brain isn't sure
exactly why not, but it has something to do with when field splitting
happens vs. when command-line substitution happens.  No amount of
quoting like you were trying to do can possibly ever fix it either.

This does work though (in both sh and ksh):

	$ for file in * ; do echo $file ; done

Filename expansion happens after field splitting so the filename
parameters stay all as single words as far as "for" is concerned.

However if you need to use 'find' for some reason, or some other list
generator (or even a list in a file) then the next best way to make this
work is to use "read" instead of command-line substitution:

	$ find . -type f -print | while read file; do echo $file; done

That'll work with all POSIX-ish shells, including /bin/sh on SunOS-5.x
(and probably earlier SysV Bourne Shell, though maybe not V7 which might
need a newline after the "read" instead of a semicolon).

-- 
								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>