The
find
command allows users to do a
comprehensive search spanning the directory tree.
find
also allows the setting of more
specific options to filter the search results and
when you?ve found what you?re looking for
find
even has the option to do some work on those files.
Finding Files by Age
What if a user wants to determine if there are
any really old files on their server? There are
dozens of options for the find command but the first
thing find
requires is the path in
which to look.
In this example we will change our working
directory to the
/
(root) directory and
run the find
command on the working
directory by giving
.
as the path
argument. The following command sequence looks for
any files that are more than 20 years, 7300 days,
old.
Finding files older than 20 years
# cd /
# find ./ -mtime +7300
./tmp/orbit-root
# cd /tmp
# ls -ld orbit-root
drwx?? 2 root root 8192 Dec 31 1969 orbit-root
By default
find
prints the name and
path to any files which match the criteria listed.
In this case it has found a file in
./tmp/orbit-root
which has not been modified
in more than 7300 days.
You?ve probably noticed that the date on this
file is a bit suspect. While the details are
unimportant it is worth understanding that anything
on a Linux system with a date of December 31, 1969
or January 1, 1970 has probably lost its date and
time attributes somehow. It may have also been
created at some time when the system?s clock was
horribly wrong.
If we wanted to search the root directory without
changing our working directory we could have
specified the directory in the find command like
this:
# find / -mtime +7300
/tmp/orbit-root
The command found the same file in this case but
has now described it starting with
/
instead of ./
because that is what was
used in the find command.
The following command sequence will look for some
newer files. The process starts in the user?s home
directory and looks for files less than three days
old.
Finding Any Files Modified in the Past 3
Days
$ cd ~
$ find . -mtime -3.
./.bash_history
./examples
./examples/preamble.txt
./examples/other.txt
./example1.fil
./.viminfo
Now we start to really see the power of the
find
command. It has identified files not
only in the working directory but in a subdirectory
as well! Let?s verify the findings with some
ls
commands:
$ ls ?alt
total 56
drwxrwxr-x 2 tclark authors 4096 Feb 3 17:45
examples
-rw??- 1 tclark tclark 8793 Feb 3 14:04 .bash_history
drwx?? 4 tclark tclark 4096 Feb 3 11:17 .
-rw??- 1 tclark tclark 1066 Feb 3 11:17 .viminfo
-rw-rw-r? 1 tclark tclark 0 Feb 3 09:00 example1.fil
$ cd examples
$ ls -alt
total 20
drwxrwxr-x 2 tclark authors 4096 Feb 3 17:45 .
-rw-rw-r? 1 tclark tclark 0 Feb 3 17:45 other.txt
-rw-rw-r? 1 tclark authors 360 Feb 3 17:44
preamble.txt
drwx?? 4 tclark tclark 4096 Feb 3 11:17 ..
-rw-r?r? 1 tclark authors 2229 Jan 13 21:35
declaration.txt
-rw-rw-r? 1 tclark presidents 1310 Jan 13 17:48
gettysburg.txt
So we see that find
has turned up
what we were looking for. Now we will refine our
search even further.
Finding .txt Files Modified in the Past 3
Days
Sometimes we are only concerned specific files in
the directory. For example, say you wrote a text
file sometime in the past couple days and now you
can?t remember what you called it or where you put
it. Here?s one way you could find that text file
without having to go through your entire system:
$ find . -name '*.txt' -mtime -3
./preamble.txt
./other.txt
Now you?ve got even fewer files than in the last
search and you could easily identify the one you?re
looking for.
Note: In Windows you can use this
equivalent to the UNIX -mtime check, see
equivalent of UNIX mtime for Windows
Find files by size
If a user is running short of disk space, they
may want to find some large files and compress them
to recover space. The following will search from the
current directory and find all files larger than
10,000KB. The output has been abbreviated.
Finding Files Larger than 10,000k
# find . -size +10000k
./proc/kcore
./var/lib/rpm/Packages
./var/lib/rpm/Filemd5s
?
./home/stage/REPCA/repCA/wireless/USData.xml
./home/stage/REPCA/repCA/wireless/completebootstrap.xml
./home/stage/REPCA/repCA/wireless/bootstrap.xml
./home/bb/bbc1.9e-btf/BBOUT.OLD
Similarly a
?
could be used in this
example to find all files smaller than 10,000KB. Of
course there would be quite a few of those on a
Linux system.
The find
command is quite flexible
and accepts numerous options. We have only covered a
couple of the options here but if you want to check
out more of them take a look at find?s man page.
Most of find?s options can be combined to find
files which meet several criteria. To do this we can
just continue to list criteria like we did when
finding .txt files which had been modified in the
past three days.
Searching for Files and Directories
The find commandallows
searching part or all of the system for files and directories based
on a number of criteria. Start off by looking for files based on
their name, but also how searching on other attributes and
automatically performing commands on the files can be done is seen.
Many of these methods can be combined into a single command to
perform very powerful and specific searches.
Searching by Name
If you know the name of a file but not where it is on the system,
you can use the find command with the -name optionto locate it. The find command expects an argument
indicating where to look for files followed by one or more options
that may have additional arguments. In this example, search the
whole system by specifying the location.
$ find /
-name tnsnames.ora
...
find: /home/areader: Permission denied
find: /u01/lost+found: Permission denied
/u01/app/oracle/product/11.1.0/db_1/network/admin/samples/tnsnames.ora
/u01/app/oracle/product/11.1.0/db_1/owb/network/admin/tnsnames.ora
find: /dev/VolGroup00: Permission denied
...
The find command prints out each location where a file by the
given name is found. Every time find encounters a location that the
user does not have permissions to read, a ‘Permission denied’ error
is printed. Unless you are logged in as root, you can expect to get
a whole lot of these when searching the entire system.
There are two ways to avoid permission errors when searching with
find. The first is to limit the scope of the search to areas where
there is read access.
$ find
/u01/app/oracle -name tnsnames.ora
/u01/app/oracle/product/11.1.0/db_1/network/admin/samples/tnsnames.ora
/u01/app/oracle/product/11.1.0/db_1/owb/network/admin/tnsnames.ora
You should do this whenever possible as it will result in faster
searches, but if you find you need to search the whole system, or at
least everywhere you have read access to on the system, there is
another method. Typically, output and errors are both printed to
the console and appear intermixed. You can manipulate that and send
errors to a file. You can choose to use a file in any directory
where you can write to, or you can use the special file /dev/null
which causes the output to disappear.
The error output is redirected by indicating 2>/dev/null after
the command. The error output is identified as 2, and this
essentially takes its output and deletes it. The final command
would look something like this.
$ find /
-name tnsnames.ora 2>/dev/null
/u01/app/oracle/product/11.1.0/db_1/network/admin/samples/tnsnames.ora
/u01/app/oracle/product/11.1.0/db_1/owb/network/admin/tnsnames.ora
It may be tempting to use this kind of redirection often, but be
careful. This causes all errors for the given command to be omitted
from the results, so it is best to use it only when it is known what
is going to be ignored.
NOTE: Typically,
a directory called lost+found is seen on each partition. If
files are recovered as part of a file system check, they are
put in this directory. Only root has access to this
directory, so it often gives a permission error when
searching with find.
|
The method above works very efficiently if the entire name of a
file is known, but sometimes only part of the name may be known or
searching for files matching a certain pattern may be desired. This
can be accomplished with wildcards.
While there are other wildcards, the * is most frequently used and
matches any string, including a blank string, in its place.
$ find /u02
-name "*.dbf"
find: /u02/lost+found: Permission denied
/u02/oradata/TEST/temp01.dbf
/u02/oradata/TEST/example01.dbf
/u02/oradata/TEST/sysaux01.dbf
/u02/oradata/TEST/users01.dbf
/u02/oradata/TEST/undotbs01.dbf
/u02/oradata/TEST/system01.dbf
When searching using wildcards, the search string must be put in
quotes - single or double will work. This allows the wildcard to be
passed in as part of the parameter to be interpreted by the find
command rather than it being interpreted by the shell.
Searching by Other Attributes
The search commandsupports
searching by practically any of the file attributes that have been
covered so far in this chapter. Here are some common examples.
Searching for Recently Modified Files
The find option -mtime allows looking for files that have been
modified less than or greater than a given number of days ago. The
number of days is given after the -mtime optionand ‘-’ is specified to search for files modified less
than the given number of days ago, or ‘+’ to search for files
modified more than the number of days ago. This example finds files
modified within the past day.
$ find /u01 -mtime
-1
find: /u01/lost+found:
Permission denied
/u01/app/oracle/diag/tnslsnr/oelinux-test1/listener/trace/listener.log
/u01/app/oracle/diag/tnslsnr/oelinux-test1/listener/alert/log.xml
/u01/app/oracle/diag/rdbms/test/TEST/trace
...
As another example, specifying -mtime +7 will return a list of
files with modification dates more than seven days ago.
Searching for Files Owned by a Specific User
Using the -user option, all files in a location owned by a
specific user can be quickly identified. To be sure of the accuracy
of the results, a command like this should be run as root.
# find /home
-user jemmons
/home/jemmons
/home/jemmons/.metacity
/home/jemmons/.metacity/sessions
...
Searching by File Size
The -size optionof find
allows searching for files larger or smaller than a specific size.
After the -size option, the size can be specified in kilobytes (k),
megabytes (M) or gigabytes (G) amongst other measures. It is
possible to search for a file of an exact size, but more likely a +
needs to be used to indicate files larger than a given size or - to
indicate files smaller.
$ find /u02 -size
+500M
find: /u02/lost+found:
Permission denied
/u02/oradata/TEST/sysaux01.dbf
/u02/oradata/TEST/system01.dbf
This example searches for files larger than
500 MB.
Finding a Specific Type of File
The find command can search for specific file types using the
-type option. Types are defined in the same way they are indicated
in the first column of the ls -l output
with the addition of f indicating regular files. This example finds
all the symbolic links in the /u01 directory.
$ find /u01 -type
l
find: /u01/lost+found:
Permission denied
/u01/app/oracle/product/11.1.0/db_1/bin/lbuilder
/u01/app/oracle/product/11.1.0/db_1/precomp/public/SQLCA.H
/u01/app/oracle/product/11.1.0/db_1/precomp/public/ORACA.FOR
/u01/app/oracle/product/11.1.0/db_1/precomp/public/ORACA.COB
...
The -type option is not overly useful by itself but can be a good
way to specify only certain file types when using other options.
Searching by Inode and Identifying Hard Links
When multiple hard linksexist
for the same file, it is indicated in the second column of the ls -l
output, but there is no indication where the links can be found.
The find commandoffers a couple
of ways to search for multiple links to the same file.
If the inode number of a file is viewed using ls -i, then use the
find command with the -inum option to search for other locations
where the inode number is in use.
# ls -i gunzip
983087 gunzip
# find / -inum
983087
/bin/zcat
/bin/gunzip
/bin/gzip
It is important to examine this output to make sure items from
other file systems are not listed since they would not represent the
same file. A simpler way to locate hard links to a given file is
using the -samefile option. Rather than taking an inode number,
this option takes a file name as an argument and identifies all file
names hard linked to this file.
# find / -samefile
./gzip
/bin/zcat
/bin/gunzip
/bin/gzip
Performing Commands on Search Results
The default behavior of the find command is to print out a list
of files found matching the given criteria. You can override this
default and perform a specific operation on a file using the -exec
option. The syntax is a little tricky, so start with an example.
$ find
/u01/app/oracle/diag/rdbms/test/TEST/trace -mtime +30 -exec rm {} \;
This command searches in the trace location for files with a
modification time of greater than 30 days ago and removes them. The
rm commandis given as an
argument after the -exec option. Each time a file is found matching
the search criteria, the name of the found file is substituted into
the command in place of the ‘{}’ curly braces and the command is
executed. The escaped semicolon ‘\;’ indicates the end of the -exec
command.
A command like this can be powerful but also very dangerous.
Great care must be taken to make sure find does not execute its
command on files it was not intended for. One way to test this type
of command is to use ls -l as the command after the -exec to view
the results and make sure the correct files are being found before
using more destructive commands like rm with find.
Combining Search Criteria
Any of the search criteria listed above can be combined to make
more specific searches possible. The order of the options is not
important as long as each option is accompanied by its own
arguments. Here is a more specific example of the find command
shown above. This goes further in specifying a pattern for the file
name and the file type.
$ find /u01/app/oracle/diag/rdbms/test/TEST/trace -name "*.trm"
-type f -mtime +30 -exec rm {} \;
The more specific the DBA can be with a find command the better,
especially when a command is reused or run automatically through
cron or at.