How to Use the Find Command In Linux

Reading Time: 11 minutes
Find Logo

One of the most popular command-line utilities is the find command, mainly because of its simplicity and versatility. It's the default option to search for files across multiple UNIX based systems with a wide range of parameters and variables to narrow down our searches. It helps look for files matching a specific name, date, size, or even owner to provide a frame to append other commands to the list of files found. The basic structure of the find command is as follows. 

find [parameters] [path] [search patterns] 

Basic Searches

While the above syntax looks simple, with this utility, you can perform complex searches without trouble. This article discusses some of the most useful search patterns to make the most out of this command. Using the find command without any parameters, it will find all files or directories in the current location.

LiquidWeb$ find
 .
 ./bad_script.sh
 ./script.sh
 ./big.log
 ./test.txt
 ./example.file
 ./Example.file.
/exAmpLe.file
./example.directory
./image.png
./app.php

Now let’s see how to do more specific queries.

Find a File or Directory By Name

The number one use for the find command is the basic file/directory search. If you want to search for a file or directory by name, you must use the -name tag (or -iname for case insensitive checks).

LiquidWeb$ find . -name
 "example.file"
 ./example.file
LiquidWeb$ find . -iname
"example.file"
./example.file
./Example.file
./exAmpLe.file

Here you use a period (.) to represent the current directory. However, this can be substituted by any location on the directory tree. The -name tag displays only the exact matches to the name, whereas the -iname tag displays any matches, no matter if they have uppercase or lowercase letters.

You can be more specific and limit the find command to look for files, directories, or other file types. The asterisk wildcard operator (*) means 0 or more characters. In the example, it matches any file that starts with the word example. With the wildcard operator’s help, you see that the first statement does not consider the file type.

LiquidWeb$ find . -iname "example*"
 ./example.file
 ./Example.file
 ./example.directory
 ./example.directory/example2.file
 ./exAmpLe.file

By adding the flag -type, you can narrow it down to only files or directories.

LiquidWeb$ find . -iname "example*" -type f
 ./example.file
 ./Example.file
 ./example.directory/example2.file
 ./exAmpLe.file
 LiquidWeb$ find . -iname "example*" -type d
 ./example.directory

To search for symbolic links, use the type -l flag. This function lists the link but not the contents to which the symbolic link points.

LiquidWeb$ find . -type l
./link.directory

lrwxrwxrwx 1 freese freese   17 Feb 28 01:35 link.directory -> example.directory

With the -type c option, you can specify to search for character devices, which are files that allow us to interact with a hardware device as if it was a regular file.

LiquidWeb$ find / -type c
/dev/apl_transport
/dev/snapctl
/dev/vcsa6
/dev/vcs6
/dev/vcsa5
/dev/vcs5
/dev/vcsa4
/dev/vcs4
/dev/vcsa3
/dev/vcs3
/dev/vcsa2
/dev/vcs2
<truncated>

Similar to the lsblk command, you can list all the block devices with the -type b option. Block devices are a special type of file that provides access to devices that store data, such as solid-state drives.

LiquidWeb$ find / -type b
/dev/sr0
/dev/vda3
/dev/vda2
/dev/vda1
/dev/vda

LiquidWeb$  lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0     11:0    1 1024M  0 rom
vda    253:0    0  100G  0 disk
|-vda1 253:1    0    1M  0 part
|-vda2 253:2    0    2G  0 part [SWAP]
`-vda3 253:3    0   98G  0 part /

Named pipe, also known as FIFO (First in, First out) files can be found with -type p.

LiquidWeb$ find . -type p
./named.pipe

prw-r--r-- 1 freese freese    0 Feb 28 05:58 named.pipe

Special Variables

There are other variables that you can add to our search to get more accurate results. 

Include Symbolic Links

Performing the same search from the previous section but introducing the directive -L, the find command accesses symbolic links (in this case, link.directory linked to example.directory) and looks for matches.

LiquidWeb$ find -L -iname "example*"
 ./example.file
 ./Example.file
 ./example.directory
 ./example.directory/example2.file
 ./exAmpLe.file
 ./link.directory/example2.file

Exclude Mount Points File Systems

The option -xdev allows the find command to list mount points or partitions in another file system, but it doesn't descend into them.

LiquidWeb$ find . -xdev -name "app*" -type f
 ./app2.php
 ./app.php

The -mount option does the same thing, so you can also use that interchangeably.

Max Depth

You can also set the range of our search by using -maxdepth. In the below example, you see that find only descended 1 level below the starting point to find all files in the /home directory.

LiquidWeb$ find /home -maxdepth 1 -type f
 /home/testing_max_depth.file

Min Depth

Using -mindepth option allows you to ignore the first directory specified and only list everything in the directory n levels below. For example, the following command will only show everything two levels below our directory but not the files at /home.

LiquidWeb$ find /home -mindepth 2 -type f
/home/freese/example2.file

Redirect Error Messages

If your search pattern is too ambiguous, you don’t have any clues about where your file is, and don’t have root directory access on our dedicated server, your screen can be filled with error messages. To avoid that, redirect the error messages to /dev/null, a unique device file that discards all data sent or written to it.

LiquidWeb$ find / -maxdepth 3 -name "my_file.txt"
 find: ‘/root’:
 Permission denied
 find: ‘/lost+found’:
 Permission denied
 LiquidWeb$ find / -maxdepth 3 -name "my_file.txt" 2>/dev/null
 LiquidWeb$

You can also redirect files found to a specific text file without the errors written out on your terminal.

LiquidWeb$ find / -maxdepth 3 -name "*file" 1>files.txt 2>/dev/null

LiquidWeb$ cat files.txt
/etc/lvm/profile
/etc/profile
/etc/skel/.profile
/home/freese/.profile
/usr/bin/byobu-select-profile
/usr/bin/file
/usr/bin/lessfile
/usr/bin/tempfile
/usr/lib/file
/usr/sbin/readprofile
/usr/sbin/xfs_mkfile
/usr/share/file

Disk Space Investigations

The find command can be very useful to determine our exact space distribution during disk investigations on our VPS server. Here are the most common uses. 

Find & List Files

One of the reasons this utility is so popular is that you can append other commands, like in the case of finding an IP, to execute the list of files you just found. The output lists the files after find retrieved all the matches.

LiquidWeb$ find . -name "*.txt" -exec ls -lh {} \;
 -rw-r--r-- 1 root root 2.0M Jan 22 15:44 ./lecture.txt
 -rw-r--r-- 1 root root 4.2M Jan 22 15:45 ./test.txt
 -rw-r--r-- 1 root root 9.5M Jan 22 15:45 ./blog.txt

Here is a breakdown of the command:

  • find . -name "*.txt": The regular search of find by name, in this case, all text files. 
  • -exec: The exec command is the option to execute commands to the list of arguments. 
  • ls -lh {}: The ls command is a command utility mainly used to list files. You also added -lh, which stands for long listing and human-readable, which prints detailed information about the files and displays the sizes in prefix multipliers (megabytes in this case). 

Find Empty Files or Directories

You see that your disk usage is relatively low in some cases, but your inodes are high. It might be caused by a disproportionate amount of empty files or directories, which you can track down using find and the tag -empty.

LiquidWeb$ find . -type f -empty
 ./empty2.file
 ./empty3.file
 ./empty.file

LiquidWeb$ find . -type d -empty
 ./empty_dir

Find Files or Directories by Date

To find files based on time, use the -newerXY directive. This is the list of options:

  • mt: modified time
  • at: access time
  • ct: inode status change
  • bt: birth time
LiquidWeb$ find . -type f !  -newermt 2021-01-23
 ./new_image.png
 ./another_app.php

LiquidWeb$ find . -type f ! -newermt 2015-12-19
./very_old_file.txt

LiquidWeb$ find . -type f ! -newerat 2015-12-19
./very_old_file.txt

In the displayed examples, you first looked for files whose modification date was equal to or newer than 2021-01-23. Subsequent statements introduced the exclamation point (!) operator, which means not. In this case, you were looking for files with a modification date older than 2015-12-19, and in the third example, we used at or access time as a parameter.

Find Files or Directories by Size

The size option lets you find specific files that exceed, match, or are below a determined size threshold. Here is a list of examples with the subsequent syntax:

  • Files with a size of exactly 950k.
  • Files with sizes above 50M.
  • Files with sizes below 25M.
  • Files with sizes within the 2M-5M range.
  • Files with sizes larger than 1GB.
LiquidWeb$ find . -type f -size 950k
 ./blog.txt (950k)

LiquidWeb$ find . -type f -size +50M
./55M_file

LiquidWeb$ find . -type f -size -25M
./20M_file

LiquidWeb$ find . -type f -size +2M -size 5M
./test.txt (4.2M)

LiquidWeb$ find / -type f -size +1G
./1G_file

Find and Delete

To remove unwanted files with the find command, add the -delete option to the files list.

LiquidWeb$ find /var/log/ -name "*.temp" -delete
LiquidWeb$
Note:
Be careful while using -delete, as it is data destructive. It’s always a good practice to look at the file list before removing them.

Before deleting anything, you should always make sure that you have good backups, that you are running the command outside of the root superuser, and that you execute a dry run first.

One of the ways you can do a dry run is by leaving only the file-finding part of the command and piping that output into less command or a file, as previously shown.

LiquidWeb$ find . -type f | less

Then you can delete the found files with the -exec flag that executes the rm (remove) command.

LiquidWeb$ find . -type f -exec rm {} \;

You can even output it to the xargs command, executing the rm command (or any other command) on each file.

LiquidWeb$ find . -type f | xargs rm

Security Oriented Inspections

If you suspect a security breach or malware infection, find can be very valuable during the preliminary investigations. 

Find Files by Permissions

Having files with 777 permissions is something to be avoided whenever possible. Using the -perm tag is really easy to find files or directories with incorrect permissions within our file system.

LiquidWeb$ find . -type f -perm 777
 ./not_malware.php 

LiquidWeb$ find . -type d -perm 777
 ./good_dir

If the files you found are not supposed to have those permissions, you can change them right away. For instance, if you want to set 644 permissions to the files, use the command below.

LiquidWeb$ find . -type f -perm 777 -exec chmod 644 {} \;

If you want to find and list out the files that do not have desired permission, for example, 644, you can use the exclamation point (!) operator, which stands for not.

LiquidWeb$ find . -type f ! -perm 644

Find Files and Directories by Owner 

Files with the incorrect owner are not necessarily malicious. However, in some instances, that can be an indication of trouble. You can easily track them down with the -user tag.

LiquidWeb$ find . -user nobody
 ./bad_script.sh

Or all files that don’t belong to that owner with the exclamation point (!) operator.

LiquidWeb$ find . -type f ! -user freese
./Example.file

-rw-r--r-- 1 root   freese    0 Feb 28 01:25 Example.file
-rw-r--r-- 1 freese freese    0 Feb 28 01:34 exAmpLe.file
drwxr-xr-x 1 freese freese 4.0K Feb 28 01:35 example.directory
-rw-r--r-- 1 freese root      0 Feb 28 01:24 example.file

Find Files and Directories By Group

You can also use the -group option to find all files that belong to a certain group.

LiquidWeb$ find . -type f -group root
./example.file

-rw-r--r-- 1 freese root      0 Feb 28 01:24 example.file

Or all files that don’t belong to group with the exclamation point (!) operator.

LiquidWeb$ find . -type f ! -group freese
./example.file

-rw-r--r-- 1 root   freese    0 Feb 28 01:25 Example.file
-rw-r--r-- 1 freese freese    0 Feb 28 01:34 exAmpLe.file
drwxr-xr-x 1 freese freese 4.0K Feb 28 01:35 example.directory
-rw-r--r-- 1 freese root      0 Feb 28 01:24 example.file

Find Files by Modification Time

You can list the files based on the modification time. The -atime option is handy to determine the accessed files within a defined interval of days. In the first and second examples, you want to find files accessed within the last 30 days and the files accessed anytime before the last 30 days.

For the third command, you'll be looking at the modification time instead. These directives follow the same pattern as those discussed in the Find Files or Directories by Date section. 

LiquidWeb$ find . -name "*.png" -atime -30
 ./new_image.png 

LiquidWeb$ find . -name "*.png" -atime +30
./old_image.png

LiquidWeb$ find . -name "*.txt" -mtime -30
 ./lecture.txt
 ./test.txt
 ./blog.txt

If you want a much more precise time down to minutes, use the -amin, -mmin, and -cmin flags.

Example of a file with its permissions changed less than five minutes ago.

LiquidWeb$ find . -type f -mmin -5
./exAmpLe.file

Searching for Advanced Permissions

You can search for files with special permissions, such as SUID, SGID, and Sticky Bit.

  • Set User ID (SUID) (4) - Runs the file as the user-owner of that file.
  • Set Group ID (SGID) (2) - Runs the file as the group-owner of that file or directory.
  • Sticky Bit (1) - Only the file owner or root can delete that file.

While not used as much generally,  finding SUID permissions can be particularly useful for security reasons, as a malicious actor can abuse this permission to keep a backdoor in your system.  You can use the permission (perm) flag with /4000 to find files with SUID, regardless of their permissions for the standard user, group, and nobody permissions.

LiquidWeb$ find . -type f -perm /4000
./suidfile

-rwSr--r--  1 root root    0 Feb 28 17:18 suidfile

Generally more used than SUID, the SGID executes a file as the group owner, or if set on a directory, makes all newly created files be owned by the directory group owner, which allows people in that directory and group to work on shared files.

LiquidWeb$ find . -type f -perm /2000
./sgidfile


-rw-r-Sr--  1 root root    0 Feb 28 17:18 sgidfile


[root@host LiquidWeb]# find . -type d -perm /2000
./group


drwxr-sr-x  2 root root 4.0K Feb 28 17:50 group

Searching for files with the sticky bit permission.

LiquidWeb$ find . -type f -perm /1000
./stickyfile

-rw-r--r-T  1 root root    0 Feb 28 17:01 stickyfile

Real-World Use Examples

Here are some practical examples using the find command. Assume the server is a CentOS-based server with a cPanel, and most of the sites use WordPress.

Finding a Specific WordPress Plugin 

Let's say you want to see which one of your cPanel account primary domains has the Akismet plugin installed. You can use a wildcard (*) to search all cPanel users on the server to the WordPress plugin directories at /home/<user>/public_html/wp-content/plugins.

[root@host home]# find /home/*/public_html/wp-content/plugins/ -maxdepth 1 -type d -name akismet
/home/testcpanelone/public_html/wp-content/plugins/akismet
/home/testcpaneltwo/public_html/wp-content/plugins/akismet
/home/testcpanelthree/public_html/wp-content/plugins/akismet
/home/testcpanelfour/public_html/wp-content/plugins/akismet

You can then use the cut command to filter out and show only the cPanel usernames that have that plugin.

[root@host lol]# find /home/*/public_html/wp-content/plugins/ -maxdepth 1 -type d -name akismet | cut -d / -f3
testcpanelone
testcpanetwo
testcpanethree
testcpanelfour

Finding WordPress Databases

While you could log in to each cPanel account and look into the databases, it is a time-consuming process. Instead, you can list them all quickly with the find command. This way, you can parse results further in combination with other commands if desired.

[root@host home]# find /home/*/public_html/wp-config.php -maxdepth 1 -type f -exec grep 'DB_NAME' {} \;
define( 'DB_NAME', 'redacted_wp764' );
define( 'DB_NAME', 'redacted_wp_a8b5d' );
define( 'DB_NAME', 'redacted_w168' );
define( 'DB_NAME', 'redacted_w735' );
define( 'DB_NAME', 'redacted_wp733' );
define( 'DB_NAME', 'redacted_base1' );
define( 'DB_NAME', 'redacted_wp_couao' );

Finding the Largest Files on the Server

A full root partition can be dangerous for your server. You can use the find command to quickly find the largest files so that you can delete unnecessary files and create extra space.

The following command looks at the root partition only and for files larger than 10 MB, then sorts them numerically, with the largest starting at the top and showing the ten biggest files.

[root@host home]# find  / -mount -type f -size +10M -exec ls -lh {} \; | awk '{print $5,$9}' | sort -rn | head
716M /home/temp/mysql/ibdata1
716M /home/temp/mysql2/mysql/ibdata1
243M /usr/sbin/mysqld
191M /var/softaculous/magento2/sampledata.zip
187M /home/temp/files/archive/home/freese/public_html2/tar.gz
184M /usr/local/cpanel/3rdparty/share/clamav/tmp.b7db27c89b/clamav-a512fbf707705b5446b4f4e38528cfcb.tmp-daily.cld
184M /usr/local/cpanel/3rdparty/share/clamav/daily.cld
182M /var/log/apache2/suphp_log
178M /usr/local/cpanel/3rdparty/share/clamav/tmp.f140459efc/clamav-51472992fecea88772f8ad9e2ec36772.tmp-daily.cld
178M /usr/local/cpanel/3rdparty/share/clamav/tmp.4342faf275/clamav-98d577c1c3465b22a0753c9b0ca2cdd3.tmp-daily.cld

Alternatively, specify with the -name command to only look for the biggest log files.

[root@host mysql]# find  /  -mount -type f -name "*log" -size +5M -exec ls -lh {} \; | awk '{print $5,$9}' | sort -rn | head
182M /var/log/apache2/suphp_log
145M /var/log/chkservd.log
125M /var/log/apache2/access_log
113M /usr/local/cpanel/logs/access_log
40M /var/log/imunify360/console.log
38M /usr/local/cpanel/logs/queueprocd.log
37M /usr/local/cpanel/logs/error_log
19M /usr/local/cpanel/3rdparty/libexec/git-core/git-shortlog
19M /usr/local/cpanel/3rdparty/libexec/git-core/git-reflog
19M /usr/local/cpanel/3rdparty/libexec/git-core/git-log

Conclusion

This tutorial walks through several practical uses for the find command. Not only can you find files or directories, but it’s easy to perform disk investigations or notice strange patterns with your files when in doubt of malicious actions. This article only scratched the surface of what the find command can do when you append other commands to its list of files. There is no doubt that this is a powerful tool with many potential applications in data manipulation.

FAQ

What is the find Linux command?

How do I find a file on Linux?

How do you use find and locate to search for files on Linux?

Avatar for Freddy Reese

About the Author: Freddy Reese

Freddy works in the Liquid Web Managed Hosting Support team with a strong passion for all things related to Linux administration, cybersecurity, and aviation. In his free time, he likes to keep up with the latest news on topics ranging from fusion to space technologies. His hobbies include automating all kinds of stuff using Arduino/Raspberry Pi, learning and flying around in flight simulators, playing with his dog Chupko, swimming at nearby beaches, and staying physically and mentally healthy by going to the gym.

Latest Articles

How to use kill commands in Linux

Read Article

Change cPanel password from WebHost Manager (WHM)

Read Article

Change cPanel password from WebHost Manager (WHM)

Read Article

Change cPanel password from WebHost Manager (WHM)

Read Article

Change the root password in WebHost Manager (WHM)

Read Article