3

I have a directory, dir1 which contains many files whose names end in either .jpg or .png. I want to copy all the .png files to dir2 which is empty.

This command works:

find dir1 -name '*.png' -exec cp {} dir2 \;

but this command doesn't:

find dir1 -name '*.png' -exec cp {} dir2 +
find: missing argument to `-exec'

I also tried:

find dir1 -name '*.png' -exec cp {} -t dir2 +
find: missing argument to `-exec'

and:

find dir1 -name '*.png' -exec cp {} dir2 \+
find: missing argument to `-exec'

After looking at this page, I even tried:

find dir1 -name '*.png' -exec cp {} dir2 {} +
find: Only one instance of {} is supported with -exec ... +

This page says that:

-exec {} + was added in [version] 4.2.12 in 2005

My version of find is 4.4.2.

What am I doing wrong?

  • 2
    Try -exec cp -t dir2 {} + – steeldriver Sep 11 '15 at 2:35
  • Thanks, that works. But why does changing ; to + mean that I have to change the order and add -t? – EmmaV Sep 11 '15 at 2:44
  • 2
    You can't insert anything between {} and + in -exec ... {} +. Note that -t is GNU extension. – cuonglm Sep 11 '15 at 2:53
4

Thanks to 'steeldriver', I've worked out that the answer is because POSIX specification forbids anything from being between {} and + after -exec.

2

There is of course a POSIX compliant solution for the problem:

find dir1 -name '*.png' -exec sh -c 'cp "$@" dir2' null {} +

There is no need to use nonstandard vendor specific features.

BTW: AFAIK, the execplus feature was introduced in 1989 by David Korn while working for SVr4. An important background information is: POSIX does not define new features but just standardizes existing solutions, so if the POSIX standard is in conflict with the solution that was the master, POSIX is usually wrong.

There is a prominent recent example: waitid() was also introduced by SVr4 in 1989 and defines that all 32 bits from the exit code must be made available to the parent. The SUSv2 standard (from 1997) was correct, but for unknown reasons, later versions mentioned that the exit code has to be masked by 0xFF. This was recently identified to be a POSIX bug.

  • Thank you for the alternative command, even if it's much harder to remember than the -t method. – EmmaV Sep 12 '15 at 1:02
  • Well, a method that needs a non-standard program is not a good idea and even if you have gcp available, it does not support ACLs, so is is usually better to find a solution based only on standard features. – schily Sep 12 '15 at 8:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.