Passing wildcard parameters to find via a variable

I have a script to fix permissions which is made up of blocks like:

FS_ROOT=/home/shared/Photos
FS_EXCLUDE=( \( -path */.webviews -o -path */.thumbnails \) -prune -o )
find $FS_ROOT ${FS_EXCLUDE[@]} -type d -not -perm 2770 -exec chmod 2770 "{}" \;

That fragment works as expected, but no matter what I try I cannot get the following to work:

FS_ROOT=/home/myhome
FS_EXCLUDE=( \( -path $FS_ROOT/dev -o -path $FS_ROOT/.\* \) -prune -o )
find $FS_ROOT ${FS_EXCLUDE[@]} -type d -not -perm 2770 -exec chmod 2770 {} \;

Without using an array to store the prune parameters it works on the command line and in a script, so there is nothing wrong with the find command itself. But when using the array it is matching hidden files.

I have tried different levels of escaping in case I needed to also escape the slash, but it made no difference.

Also I have tried using escaped single quotes, and running the script in sh and bash modes. The only difference with the latter was a single escaping slash in bash mode causes the wildcard to expand, the same as if no slash was used.

I want to use a variable to hold these parameters though as they are repeated on other find commands for file permissions and ownership, so any help on how to get this to work would be appreciated.

Michael.

Try to quote the variables:

FS_ROOT=/home/sysadmin/t
FS_EXCLUDE=( \( -path "$FS_ROOT/dev" -o -path "$FS_ROOT/.*" \) -prune -o )
find "$FS_ROOT" "${FS_EXCLUDE[@]}" -type d -not -perm 2770 -exec chmod 2770 {} \;

If that doesn't work, please post an example:

  • sample directory tree
  • sample command, the actual and the expected output
1 Like

It is always something simple! I probably should quote everything anyway to be safe, I do have files with spaces, but just quoting the ${FS_EXCLUDE[@]} variable was the missing piece to make the script work.

I am struggling to see the logic of why it makes a difference, though, as surely when the array elements are unpacked they would be within the quotes and so passed as a single parameter?

Anyway, it works now, so many thanks.

Michael.

I believe the main problem was the wild card expansion: the * was expanded in the current working directory of the script.