find not returning expected files

In your command, the sudo only gives extra privileges to the find command, not to the shell. So if you start up high, find is able to descend into the filetree and show you the contents.

But your shell is trying to expand the *. If your user does not have privileges to inspect the contents of /nfshome/*/.local, then it will not be able to match to any files within (such as /nfshome/*/.local/share). Without a match, nothing is passed to find.

You can see this by examining the output of echo /nfshome/*/.local and echo /nfshome/*/.local/share. The second will probably be empty.

It's not clear why you want to do the second command when the first one appears to work. You could run the entire command in a subshell, and execute it with sudo. Such as sudo -c "find ..."


The reason this fails is to do with permissions and the wildcard * character. We can reproduce this on a local file-system like this:

  1. Set up the scenario, a directory tree under /tmp/top:

    sudo -s <<'x'
    mkdir -p /tmp/top/{a,b}/dir/sub/
    touch /tmp/top/{a,b}/dir/sub/file
    chown root /tmp/top/?/dir
    chmod go= /tmp/top/?/dir
    x
    
  2. Notice that we have no permission as an ordinary user to go below /tmp/top/*/dir:

    find /tmp/top/?/dir -type f
    find: ‘/tmp/top/a/dir’: Permission denied
    find: ‘/tmp/top/b/dir’: Permission denied
    
  3. Try descending with root privileges from a directory that we cannot reach as an ordinary user:

    sudo find /tmp/top/*/dir/sub -type f
    find: ‘/tmp/top/*/dir/sub’: No such file or directory
    

    Remember the evaluation of shell wildcards happens before the command is executed. So what is happening here is that the path containing the wildcard * is expanded. Your ordinary user account cannot verify the existence of sub, and so the entire path cannot be verified. The wildcard remains as an asterisk (the default behaviour when a match fails) and the root privileged find is given the literal path /tmp/top/*/dir/sub to descend. This path does not exist, hence the error.

  4. Try descending with root privileges from a directory that we can reach as an ordinary user:

    sudo find /tmp/top/*/dir -type f
    /tmp/top/a/dir/sub/file
    /tmp/top/b/dir/sub/file
    

    What happens here is similar, but with more useful consequences. The path /tmp/top/*/dir can be evaluated completely as your ordinary user, resulting in two paths /tmp/top/a/dir and /tmp/top/b/dir. These are passed to the root privileged find, and it can subsequently descend these - through the root-only subdirectory - and list the files it discovers.

In your situation, it is highly likely that the .local directories in your wildcarded path cannot be accessed without root privileges, but the higher level directories are quite accessible. While you specify a path that can be evaluated as your ordinary user account, the find can proceed with the expanded set of paths. As soon as you specify a path that cannot be evaluated in the context of your ordinary user account, the expansion fails and find is passed a path that contains a literal * character. This of course fails to match and the find fails.

To resolve the issue you simply need to defer the evaluation of the path until your command is running as root:

sudo bash -c "find /nfshome/*/.local/ -type f -size +1G -exec ls -lh {} \;"

Tags:

Find