1 |
On Tuesday 09 June 2009 17:20:49 Etaoin Shrdlu wrote: |
2 |
> On Tuesday 9 June 2009, 16:36, Neil Bothwick wrote: |
3 |
> > On Tue, 09 Jun 2009 16:15:21 +0200, Joerg Schilling wrote: |
4 |
> > > > find -H /usr/lib /lib -type f | xargs -d'\n' qfile --orphans |
5 |
> > > |
6 |
> > > No, this is definitely wrong: the right way to handle this is |
7 |
> > > execplus (since 19 years). |
8 |
> > |
9 |
> > If it's been around 19 years, why doesn't Google know anything about |
10 |
> > it? What is it? |
11 |
> |
12 |
> Well, google does not know everything :) |
13 |
> |
14 |
> Basically, using + instead of ; after -exec allows to run the specified |
15 |
> command less times, each time with the highest possible number of |
16 |
> arguments (instead of running it once per file, which is what happens |
17 |
> with ;). And yes, that's been in POSIX for a long time now. Example: |
18 |
> |
19 |
> |
20 |
> $ ls |
21 |
> file1 file2 file3 file4 file5 |
22 |
> |
23 |
> $ find . -type f -exec sh -c 'echo "number of arguments: $#"' sh {} \; |
24 |
> number of arguments: 1 |
25 |
> number of arguments: 1 |
26 |
> number of arguments: 1 |
27 |
> number of arguments: 1 |
28 |
> number of arguments: 1 |
29 |
> |
30 |
> $ find . -type f -exec sh -c 'echo "number of arguments: $#"' sh {} + |
31 |
> number of arguments: 5 |
32 |
> |
33 |
> So when you have to run a command on a very big number of files, say 1000 |
34 |
> or more, with ; you spawn 1000 processes, with + you span just one or |
35 |
> two (well, depending on the maximum command line length on the system |
36 |
> anyway). This is of course much less resource intensive. |
37 |
|
38 |
Some numbers. |
39 |
|
40 |
These are from memory, I ran these commands today while preparing a machine |
41 |
for an installation of a package. The directory tree at the starting point had |
42 |
about 5000 files, more than 80% with a UID not attached to an account: |
43 |
|
44 |
chown -R <user>:<group> * |
45 |
about 2 seconds |
46 |
|
47 |
find . -nouser -o -nogroup -exec chown <user>:<group> {} + |
48 |
about 30 seconds (wild guess) |
49 |
|
50 |
find . -nouser -o -nogroup -exec chown <user>:<group> {} \; |
51 |
I killed this one after 5 minutes and it was nowhere near complete |
52 |
|
53 |
Admittedly, this was on a vmware guest with a rather poor disk configuration, |
54 |
but it does illustrate that the naive "find \;" performs extremely poorly. |
55 |
chown on it's own is foolish as the whole point of the exercise was to find |
56 |
files meeting certain criteria, and there was definitely some that didn't. |
57 |
|
58 |
execplus is a fine middle ground giving the best possible bang for buck. |
59 |
|
60 |
-- |
61 |
alan dot mckinnon at gmail dot com |