1. Overview

In this tutorial, we’ll look at how to exclude permission errors while searching a Linux filesystem. We’ll focus on how to avoid these messages while working interactively on the command line.

The commands have been tested on Debian 11. All code snippets should work in most Linux environments.

2. Linux find Command

The find command is widely used to search for files.

When run without any parameters, find defaults to searching the file tree of the current working directory. Here, let’s run the whoami command, to show the current user name, and follow this with find without any parameters:

$ whoami
alice
$ find
.
./ansible
./apache
./alice
./alice/test_results
./alice/test_results/test.img
./alice/docs

We see that we got the directory listing and the file names of the subdirectories where the user has permission to access the files.

Now, let’s have a look at running find with parameters that include descending into directories where the user doesn’t have permission to access the files, and handling the resulting errors.

3. Redirecting Errors

In this example, we’re going to search for a file in the /var/log filesystem. We’ll include the filesystem path, and we’ll pass the parameter -iname to specify a filename and let the match be case insensitive.

Without sudo permission, this will trigger “Permission denied” errors:

$ $ find /var/log -iname results.log
find: ‘/var/log/apache2’: Permission denied
find: ‘/var/log/private’: Permission denied

To omit those errors from our output, we can redirect the standard error stream, commonly represented as the number 2, to dev/null. Let’s combine our stream number followed by the redirection symbol “>” to /dev/null and append this to our command:

$ find /var/log -iname results.log 2>/dev/null
/var/log/testing/results.log

On a system where /var/log could hold a lot of log directories with different file permissions, this will prevent the need to scroll through many lines of permission errors in our output.

4. Error Filtering

In the above example, we redirected all error output from our terminal. If we prefer to omit only the specific permission errors, we can combine find with awk and xargs to customize the input to our command:

$ ls -lG /var/log/ | awk '/alice/ {print $NF}' | xargs -I {} find /var/log/{} -iname results.log
/var/log/testing/results.log

Let’s break down what that command did:

First, we limit our search to directories where the current user (alice in our example) is the owner. This omits the permission errors from other directories. We do this with ls, including the parameters -l for long listing and G to not print groups — we’re going to use the owner name in the next command, so we want to avoid a duplicate entry of the name:

$ ls -lG /var/log/
total 680
-rw-r--r--  1 root      4088 Aug 28 19:01 alternatives.log
drwxr-x---  2 root      4096 Aug 28 16:47 apache2

Then, we use awk to find the owner name in the ls output and print the last field of that line. That will be the sub-directory name, testing in our example:

$ ls -lG /var/log/ | awk '/alice/ {print $NF}' 
testing

Finally, we use xargs to execute our find command, including the parameter -I to buffer the input of the sub-directory name as the path to search. So, we have our original find command, except find substitutes the sub-directory path of the selected directory for “{}”:

$ ls -lG /var/log/ | awk '/alice/ {print $NF}' | xargs -I {} find /var/log/{} -iname results.log
/var/log/testing/results.log

By combining these commands, we filter our results to omit error messages concerning permissions.

5. Conclusion

In this article, we learned how to omit permission-denied messages when searching for Linux files on the command line.

We started with a look at the find command, and we saw how to redirect the standard error output so that it doesn’t print to the terminal.

Finally, we ran a combination of commands to filter for directories owned by the user and then used these directory names as the input for our file search.