379 Jun 29 2014 ./.bashrc # find /home \( -user chris -or -user joe \) -ls 131077 4 -rw-r--r-- 1 chris chris 379 Jun 29 2014 ./.bashrc 181022 4 -rw-r--r-- 1 joe joe 379 Jun 15 2014 ./.bashrc # find /etc -group ntp -ls 131438 4 drwxrwsr-x 3 root ntp 4096 Mar 9 22:16 /etc/ntp # find /var/spool -not -user root -ls 262100 0 -rw-rw---- 1 rpc mail 0 Jan 27 2014 /var/spool/mail/rpc 278504 0 -rw-rw---- 1 joe mail 0 Apr 3 2014 /var/spool/mail/joe 261230 0 -rw-rw---- 1 bill mail 0 Dec 18 14:17 /var/spool/mail/bill 277373 2848 -rw-rw---- 1 chris mail 8284 Mar 15 2014 /var/spool/mail/chris
The first example outputs a long listing of all of the files under the /home
directory that are owned by the user chris
. The next lists files owned by chris
or joe
. The find
command of /etc
turns up all files that have ntp
as their primary group assignment. The last example shows all files under /var/spool
that are not owned by root. You can see files owned by other users in the sample output.
Finding files by permission
Searching for files by permission is an excellent way to turn up security issues on your system or uncover access issues. Just as you changed permissions on files using numbers or letters (with the chmod
command), you can likewise find files based on number or letter permissions along with the -perm
options. (Refer to Chapter 4, “Moving Around the Filesystem,” to see how to use numbers and letters with chmod
to reflect file permissions.)
If you use numbers for permission, as I do below, remember that the three numbers represent permissions for the user, group, and other. Each of those three numbers varies from no permission (0) to full read/write/execute permission (7) by adding read (4), write (2), and execute (1) bits together. With a hyphen (-
) in front of the number, all three of the bits indicated must match; with a forward slash (/) in front of it, any of the numbers can match for the search to find a file. The full, exact numbers must match if neither a hyphen nor a forward slash is used.
Consider the following examples:
$ find /usr/bin -perm 755 -ls 788884 28 -rwxr-xr-x 1 root root 28176 Mar 10 2014 /bin/echo $ find /home/chris/ -perm -222 -type d -ls 144503 4 drwxrwxrwx 8 chris chris 4096 Jun 23 2014 /home/chris/OPENDIR
By searching for -perm 755
, any files or directories with exactly rwxr-xr-x
permission are matched. By using -perm -222
, only files that have write permission for user, group, and other are matched. Notice that, in this case, the -type d
is added to match only directories.
$ find /myreadonly -perm /222 -type f 685035 0 -rw-rw-r-- 1 chris chris 0 Dec 30 16:34 /myreadonly/abc $ find . -perm -002 -type f -ls 266230 0 -rw-rw-rw- 1 chris chris 0 Dec 30 16:28 ./LINUX_BIBLE/abc
Using -perm /222
, you can find any file (-type f
) that has write permission turned on for the user, group, or other. You might do that to make sure that all files are read-only in a particular part of the filesystem (in this case, beneath the /myreadonly
directory). The last example, -perm /002
, is very useful for finding files that have open write permission for “other,” regardless of how the other permission bits are set.
Finding files by date and time
Date and time stamps are stored for each file when it is created, when it is accessed, when its content is modified, or when its metadata is changed. Metadata includes owner, group, time stamp, file size, permissions, and other information stored in the file's inode. You might want to search for file data or metadata changes for any of the following reasons:
You just changed the contents of a configuration file, and you can't remember which one. So, you search /etc to see what has changed in the past 10 minutes: $ find /etc/ -mmin -10
You suspect that someone hacked your system three days ago. So, you search the system to see if any commands have had their ownership or permissions changed in the past three days: $ find /bin /usr/bin /sbin /usr/sbin -ctime -3
You want to find files in your FTP server (/var/ftp) and web server (/var/www) that have not been accessed in more than 300 days so that you can see if any need to be deleted: $ find /var/ftp /var/www -atime +300
As you can glean from the examples, you can search for content or metadata changes over a certain number of days or minutes. The time options (-atime
, -ctime
, and -mtime
) enable you to search based on the number of days since each file was accessed, changed, or had its metadata changed. The min
options (-amin
, -cmin
, and -mmin
) do the same in minutes.
Numbers that you give as arguments to the min
and time
options are preceded by a hyphen (to indicate a time from the current time to that number of minutes or days ago) or a plus (to indicate time from the number of minutes or days ago and older). With no hyphen or plus, the exact number is matched.
Using ‘not' and ‘or' when finding files
With the -not
and -or
options, you can further refine your searches. There may be times when you want to find files owned by a particular user but not assigned to a particular group. You may want files larger than a certain size but smaller than another size. Or you might want to find files owned by any of several users. The -not
and -or
options can help you do that. Consider the following examples:
There is a shared directory called /var/allusers. This command line enables you to find files that are owned by either joe or chris. $ find /var/allusers \( -user joe -o -user chris \) -ls 679967 0 -rw-r--r-- 1 chris chris 0 Dec 31 12:57 /var/allusers/myjoe 679977 1812 -rw-r--r-- 1 joe joe 4379 Dec 31 13:09 /var/allusers/dict.dat 679972 0 -rw-r--r-- 1 joe sales 0 Dec 31 13:02 /var/allusers/one
This command line searches for files owned by the user joe, but only those that are not assigned to the group joe: $ find /var/allusers/ -user joe -not -group joe -ls 679972 0 -rw-r--r-- 1 joe sales 0 Dec 31 13:02 /var/allusers/one
You can also add multiple requirements on your searches. Here, a file must be owned by the user joe and must also be more than 1MB in size: $ find /var/allusers/ -user joe -and -size +1M -ls 679977 1812 -rw-r--r-- 1 joe root 1854379 Dec 31 13:09 /var/allusers/dict.dat
Finding files and executing commands
One of the most powerful features of the find
command is the capability to execute commands on any files that you find. With the -exec
option, the command you use is executed on every file found, without stopping to ask if that's okay. The -ok
option stops at each matched file and asks whether you want to run the command on it.
The advantage of using -ok
is that, if you are doing something destructive, you can make sure that you okay each file individually before the command is run on it. The syntax for using -exec
and -ok
is the same:
$ find [options] -exec command {} \; $ find [options] -ok command {} \;
With -exec
or -ok
, you run find
with any options you like in order to find the files you are seeking. Then you enter the -exec
or -ok
option followed by the command you want to run on each file. The set of curly braces indicates where on the command line to read in each file that is found. Each file can be included in the command line multiple times if you like. To end the line, you need to add a backslash and semicolon (\;
). Here are some examples:
This command finds any file named passwd under the /etc directory and includes that name in the output of an echo command: $ find /etc -iname passwd -exec echo "I found {}" \; I found /etc/pam.d/passwd