1

In rsync I can just define my exclusions/options in an array and use those arrays in the subsequent command, e. g.

rsync "${rsyncOptions[@]}" "${rsyncExclusions[@]}" src dest

I wanted to achieve the same using the find command but I couldn't find a way to make it work:

findExclusions=(
    "-not \( -name '#recycle' -prune \)"
    "-not \( -name '#snapshot' -prune \)"
    "-not \( -name '@eaDir' -prune \)"
    "-not \( -name '.TemporaryItems' -prune \)"
)
LC_ALL=C /bin/find src -mindepth 1 "${findExclusions[@]}" -print

In whatever combination I try to define the array (single vs double quotes, escaping parentheses) I always end up with an error:

find: unknown predicate `-not \( -name '#recycle' -prune \)'
# or
find: paths must precede expression: ! \( -name '#recycle' -prune \)

What is the correct way to do this?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
TylerDurden
  • 697
  • 1
  • 5
  • 16

1 Answers1

5

The issue here is that "-not \( -name '#recycle' -prune \)" is not one argument, it is 6 arguments. You could write it like so:

findExclusions=(
    -not '(' -name '#recycle' -prune ')'
    -not '(' -name '#snapshot' -prune ')'
)
Pierce
  • 526
  • 3
  • 4
  • Why does find parse the bracket correctly when it is enclosed within single quotes but not when escaped? – markling Apr 25 '22 at 12:56
  • You _can_ use the backslash escape for the parenthesis, instead of single quotes, I just thought the quotes were less ugly. The issue was really the quoting around the whole line. All these escapes and quoting are parsed by the shell (bash,zsh,etc), `find` does not see any of it in this case. – Pierce Apr 27 '22 at 19:48