Created Sc2044 (markdown)

David A. Wheeler
2013-12-01 08:27:54 -08:00
parent d568f3a37e
commit 3ff1272aa3

24
Sc2044.md Normal file

@@ -0,0 +1,24 @@
It is difficult to correctly use "find" in a for loop, because filenames can contain bytes such as newlines and "*". Where practical, consider using find's "-exec" like this:
find . -exec COMMAND... {} \;
find . -exec COMMAND... {} \+
A portable though complicated approach is to use a subshell (use '\'' for each single quote), though since a subshell is used, all variable assignments in the loop are lost after the loop ends:
find . -exec sh -c '
for file do
... # Use "$file" not $file
done' sh {} +
A nonstandard but widely-working simple alternative is:
find . -print0 | xargs -0 COMMAND
Using a find... while loop is another alternative. This requires nonstandard extensions to find (-print0) and shell (read -d), and fails in some cases on Cygwin (in while loops, filenames ending in \r \n and \n look identical to Cygwin). Variable values may be lost after the loop because the loop may run in a subshell:
find . -print0 | while IFS="" read -r -d "" file ; do ...
COMMAND "$file" # Use quoted "$file", not $file, everywhere.
done
For more information, see "[Filenames and Pathnames in Shell: How to do it Correctly](http://www.dwheeler.com/essays/filenames-in-shell.html)".