Mike McClain <[EMAIL PROTECTED]>: > Frank Terbeck <[EMAIL PROTECTED]> wrote: > > > > for FILE in `ls *$1` ; do > > > > Please don't teach beginners to do for loops like this. It's broken in > > various ways. Just do: > > > > for FILE in *"$1" ; do > > > > Being a self taught script writer I just have to ask what are the > 'various ways' in which the first form is broken?
a) `ls *` is an _external_ process. And performance is not the main reason we this is bad. It would have to be a lot of forks to make a notable difference. However, the big problem here is, that you can only pass a limited number of arguments to an external program. This limit is reached quicker than you might think, and it is one of the features of for-loops to _overcome_ this limitation. b) it breaks on filenames with spaces (and other special characters). While newlines and other special characters might be rather weird for filenames, spaces are perfectly okay and normal in filenames. Using 'for i in `ls *`'-type loops breaks this and is one of the main reasons why people think spaces are bad in filenames. (They are not bad, some people just do not know how to handle them properly.) c) people commonly use 'ls --color' or 'ls -F' aliases for ls. This is not a bad thing in the first place because it helps to simplify the overview you get from ls. However, it has a bad impact on scripting: [snip] % for i in `ls -F /bin/*sh` ; do stat "$i" ; done stat: cannot stat `/bin/sh@': No such file or directory % for i in `ls --color /bin/sh` ; do stat "$i" ; done stat: cannot stat `\033[00m\033[01;36m/bin/sh\033[00m': No such file or directory stat: cannot stat `\033[m': No such file or directory [snap] Using '--color=auto' instead of just '--color' helps a little with problem, but not everyone is aware of it. Yes, I know that aliases are normally not enabled in scripts, but for-loops are very handy as one-liners, so this _is_ indeed a problem. These are the main reasons that come to my mind. There might be others. I am aware that there are HOWTOs and other documents out there that propagate 'for i `ls *foobar*`' loops. I don't know why their authors do this. If they didn't know better they shouldn't have written a shell scripting HOWTO in the first place. Some people use things like this instead: [snip] ls * | while read file ; do whatever_command "$file" ; done [snap] This is just a little better than the for loop. It still breaks in some situations. Also 'for i in * ; do foo "$i" ; done' is much clearer, shorter and simpler to understand. There is _no_ reason why 'ls' should ever be used to generate file lists for loops of any kind. Whoever created this myth should be hung. :-) Oh, and doing the following will break in certain situations as well (which is something people do for recursive actions): [snip] find . -name '*' | while read file ; do foobar "$file" ; done [snap] If you need to do recursive actions, learn to use find(1) properly (with its '-exec' option), or switch to a shell, that can do it by itself (like zsh, for example). Regards, Frank -- In protocol design, perfection has been reached not when there is nothing left to add, but when there is nothing left to take away. -- RFC 1925 -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]