The find command is a useful tool for finding files and directories on our filesystem that match certain criteria. Some examples of these criteria are file size, creation time, modified time, and permissions.
While it’s straightforward to find files that have certain permissions, it is not immediately obvious how to do the opposite.
In this tutorial, we’ll see how to find files that don’t have certain permissions.
2. Finding Files With Specified Permissions
Let’s say we have a few files with various permissions:
$ ls -l -rw------- 1 user user 0 Feb 17 19:31 file1 --w------- 1 user user 0 Feb 17 19:31 file2 -rwxr--r-- 1 user user 0 Feb 17 19:31 file3 -rw-r--r-- 1 user user 0 Feb 17 19:31 file4 -rw-r--r-- 1 user user 0 Feb 17 19:31 file5 -rw-r--r-- 1 user user 0 Feb 17 19:31 file6
We can use the -perm flag of the find command to search these, based on their permissions. For example, let’s look for files that are user-executable:
$ find . -type f -perm -u+x ./file3
But now, let’s say we want the list of files that are not group readable. We might be tempted to use the -perm flag with -g-r as the parameter:
$ find . -type f -perm -g-r ./file3 ./file2 ./file4 ./file5 ./file6 ./file1
This command has returned all files that are readable by the group, which is the opposite of what we’re looking for.
3. Negating the Values of the -perm Flag
To find files that do not have specific permissions, we can use the negation (!) symbol along with the -perm flag:
$ find . -type f ! -perm -g+r ./file2 ./file1
That’s exactly what we wanted. Files file1 and file2 are not readable by other users belonging to the group.
Let’s try to understand this usage a bit further. We started by finding files that were group-readable, using the flag “-perm -g+r” to do that. Then, we negated the whole thing: “! -perm -g+r”.
Let’s try another example to get the hang of it. Here’s how we can find files that are not readable by the owner:
$ find . -type f ! -perm -u+r ./file2
And, that gives us the expected output.
4. Variations Between find Versions
The solution discussed above works on most of the common Unix-like operating systems. However, the GNU find variant has an easier way with the -readable, -writable, and -executable flags. These flags only work relative to the owner and can’t be used to find files that lack other permissions.
Let’s list all files that are executable by the logged-in user:
$ find . -type f -executable ./file3
Likewise, we can find files that are not readable by the owner:
$ find . -type f ! -readable ./file2
However, these options don’t work on BSD, macOS, or other Unix variants.
In this tutorial, we first saw how to use the find command to find files matching specific permissions. Then we saw how to use negation to find files not matching the specified permissions.