[lug] bash scripting question
Tkil
tkil at scrye.com
Sun Nov 20 05:27:47 MST 2005
>>>>> "Hugh" == Hugh Brown <hugh at math.byu.edu> writes:
Hugh> for i in *;do command "$i"; done
Interesting that this is actually more robust than the "read" version.
Consider:
| $ touch "a b" "c d"
| $ perl -e 'open $fh, ">", "sneaky\nfile" or die "open: $!";
| print $fh "boo!";'
| $ ls
| a b c d old sneaky?file
Using "read" doesn't work, because of that newline in "sneaky\nfile":
| $ ls -1 | while read file ; do echo "<$file>" ; done
| <a b>
| <c d>
| <old>
| <sneaky>
| <file>
But the "for i in *" construct works fine:
| $ for file in * ; do echo "<$file>" ; done
| <a b>
| <c d>
| <old>
| <sneaky
| file>
Note to newbies: this is why "find ... -print0" and "xargs -0 ..." are
always safer than the just plain "-print"; the latter relies on
newlines (which are legal in unix filenames) instead of forcing NUL
characters (which aren't; NUL and '/' are the only two characters that
are forbidden at the filesystem level).
Personally, as soon as I hit any quoting/splitting issue in shell that
can't be solved with simple addition of double quotes, I just bail and
go to perl where I know the rules. I'll have to remember this trick,
though, as just this last week I ran into this situation.
Happy hacking,
t.
More information about the LUG
mailing list