1 |
commit: 187db88dfd631e9e10bc2e5e710f96a64d01e169 |
2 |
Author: Göktürk Yüksek <gokturk <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sat Oct 29 16:27:05 2016 +0000 |
4 |
Commit: Göktürk Yüksek <gokturk <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Oct 31 01:09:00 2016 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/devmanual.git/commit/?id=187db88d |
7 |
|
8 |
tools-reference/find: encourage the while read loop with '-print0' |
9 |
|
10 |
The "funky while read loop" has problems coping with file names |
11 |
containing special characters. Improve it by using the '-print0' |
12 |
option that uses the NUL character to delimit the output lines, which |
13 |
can be processed safely by the while read loop by adjusting the |
14 |
delimiter settings. |
15 |
|
16 |
As for whether supplying $'\0' is an undocumented feature or not, see: |
17 |
http://lists.gnu.org/archive/html/help-bash/2016-10/msg00039.html |
18 |
|
19 |
Suggested-By: David Seifert <soap <AT> gentoo.org> |
20 |
|
21 |
tools-reference/find/text.xml | 31 ++++++++++++++++++++----------- |
22 |
1 file changed, 20 insertions(+), 11 deletions(-) |
23 |
|
24 |
diff --git a/tools-reference/find/text.xml b/tools-reference/find/text.xml |
25 |
index 4172128..8601a51 100644 |
26 |
--- a/tools-reference/find/text.xml |
27 |
+++ b/tools-reference/find/text.xml |
28 |
@@ -112,6 +112,15 @@ Useful rules include: |
29 |
</ti> |
30 |
<ti>no, GNU and FBSD</ti> |
31 |
</tr> |
32 |
+ <tr> |
33 |
+ <ti><c>-print0</c></ti> |
34 |
+ <ti> |
35 |
+ Separate file names by a NUL character instead of a newline in |
36 |
+ the output. This is useful for guarding against files which may |
37 |
+ include a newline in their names. |
38 |
+ </ti> |
39 |
+ <ti>no, GNU and FBSD</ti> |
40 |
+ </tr> |
41 |
</table> |
42 |
|
43 |
<note> |
44 |
@@ -121,30 +130,30 @@ ebuild context for those EAPIs. |
45 |
|
46 |
<p> |
47 |
By default, <c>find</c> will echo a list of matching files to the |
48 |
-standard output. This can be used in a <c>while</c> loop: |
49 |
+standard output separated by newlines. It can be combined with a |
50 |
+<c>for</c> loop for a small number of files with no weird characters |
51 |
+and spaces in their names: |
52 |
</p> |
53 |
|
54 |
<codesample lang="ebuild"> |
55 |
-while read f ; do |
56 |
+for f in $(find "${S}" -type f) ; do |
57 |
einfo "Doing unholy things to ${f}" |
58 |
-done < <(find "${S}" -type f) |
59 |
+done |
60 |
</codesample> |
61 |
|
62 |
<p> |
63 |
-Or a <c>for</c> loop (for small numbers of files): |
64 |
+The above loop may cause issues with files containing special |
65 |
+characters in their names. A better way is to run <c>find</c> with the |
66 |
+<c>-print0</c> option in a <c>while</c> loop (note the options passed |
67 |
+to <c>while</c> and <c>read</c> for changing the delimiter): |
68 |
</p> |
69 |
|
70 |
<codesample lang="ebuild"> |
71 |
-for f in $(find "${S}" -type f) ; do |
72 |
+while IFS="" read -d $'\0' -r f ; do |
73 |
einfo "Calling down holy vengance upon ${f}" |
74 |
-done |
75 |
+done < <(find "${S}" -type f -print0) |
76 |
</codesample> |
77 |
|
78 |
-<warning> |
79 |
-In both cases, files with weird characters or spaces in their names |
80 |
-may cause serious problems. |
81 |
-</warning> |
82 |
- |
83 |
<p> |
84 |
As an alternative you can use the <c>-exec</c> argument. Be careful |
85 |
with escaping to ensure that <c>bash</c> doesn't gobble up the special |