tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: find and limits

    Date:        Thu, 4 Apr 2019 10:12:35 +0000
    Message-ID:  <20190404101235.GB6947%SDF.ORG@localhost>

  | I understand the need for correctness, but the limits for find ... -exec
  | are really low,

What limits do you think are being encountered here?

  | and it's quite unclear why things fail when they do.

I can take a guess, but that is no more than what it is,
and I am not sure why it would produce the observed symptoms

  | cd /cvs/pkgsrc/fonts/urbanrenewal-ttf/
  | make patch
  | mkdir -p work/.destdir/usr/pkg/share/fonts/X11/TTF
  | find /cvs/pkgsrc/fonts/urbanrenewal-ttf/work -name '*.ttf'  -exec /usr/bin/install -c -o fly -g users -m 644 "{}" /cvs/pkgsrc/fonts/urbanrenewal-ttf/work/.destdir/usr/pkg/share/fonts/X11/TTF ";"

What you're doing there is looking for all *.ttf files under /cvs/.../work
and copying them into a subdirectory of /cvs/.../work

If the files are copied one at a time, eventually, it is likely that
find will encounter files it copied earlier, and attempt to copy the
file that was already copied (that is "install"ed).   I don't know how
install works, and why it would produce an EINVAL in that case (which is
an unusual error to get from write(2) - though not impossible) but
I'd guess this is somehow related.   (nb: this does not happen for me
when I tested install manually, so all this conjecture might be bogus.)

When you redo that find to use -print | xargs, find will have located
all the original *.ttf files in the tree (unless there are a very large
number of them) before xargs invokes install to copy anything at all.

  | this is 7 files!

That was 7 (or more) separate invocations of "install" each of which
exited when encountering the write error.

  | Can we do something about this so find .. -exec is usable in more cases?

Find -exec works just fine.   The form with '+' instead of ';' as the
terminator could have 'issues' I suppose, but that wouldn't work for you
as it requires the {} to be the last arg (immediately preceding the '+')
at least to be portable, whatever our version of find supports.

If the problem is as I have guessed, then the -print | xargs version
is only working by chance (because there are not enough files being
copied for xargs to start working before find has finished searching).

The correct solution would be to make the command more like

	find /cvs/pkgsrc/fonts/urbanrenewal-ttf/work -name .destdir -prune \
	  -o -name '*.ttf'  -exec /usr/bin/install -c -o fly -g users -m 644 \
	 "{}" /cvs/pkgsrc/fonts/urbanrenewal-ttf/work/.destdir/usr/pkg/share/fonts/X11/TTF ";"

(split onto several lines purely for the e-mail).

Since the current directory is already the parent directory of "worK"
that could be simplified to

	find work -name .destdir -prune \
	  -o -name '*.ttf' -exec /usr/bin/install -c -o fly -g users -m 644 \
	 "{}" work/.destdir/usr/pkg/share/fonts/X11/TTF ";"

though given that the directory names are likely Makefile variables
that probably isn't worth attempting (but it does make this example
fit the e-mail better).


Home | Main Index | Thread Index | Old Index