|
|
Finding Files by Age
Linux Tips by Burleson Consulting |
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 > 20 Years Old
# cd /
# 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 it's 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
-rw-r--r-- 1 tclark authors 0 Jan 27 00:22 umask_example.fil
drwxr-xr-x 8 root root 4096 Jan 25 22:16 ..
-rw-rw-r-- 1 tclark tclark 0 Jan 13 21:13 example2.xxx
-rw-r--r-- 1 tclark tclark 120 Aug 24 06:44 .gtkrc
-rw-r--r-- 1 tclark tclark 24 Aug 18 11:23 .bash_logout
-rw-r--r-- 1 tclark tclark 191 Aug 18 11:23 .bash_profile
-rw-r--r-- 1 tclark tclark 124 Aug 18 11:23 .bashrc
-rw-r--r-- 1 tclark tclark 237 May 22 2003 .emacs
-rw-r--r-- 1 tclark tclark 220 Nov 27 2002 .zshrc
drwxr-xr-x 3 tclark tclark 4096 Aug 12 2002 .kde
$ 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.
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 to save trees and ink.
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.
Doing things with what we find
The ?exec option gives find the powerful ability to
execute commands on the files found. The syntax is a little tricky but an
example is usually all it takes to get it right.
Before using the -exec option, especially with a
powerful command like rm I recommend performing the same find without the
?exec. By doing this you will see exactly which files you will be effecting
when you run the final command.
The following is a practical example that finds files
less than three days old with the .txt extension and deletes them.
Finding .txt Files < 3 Days Old and Delete Them
$ find . -name '*.txt' -mtime -3 -exec rm
{} \;
$ ls ?lt
total 8
-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
The ?exec option allows you to put any command after
it. Here we have used rm but it is often useful to use this option with cp or
chmod. Within the command to be run there must be two curly brackets {}. find
will execute the command for each file it finds substituting the file name (and
path) where the curly brackets are. Finally the end of the ?exec option is
signaled by an escaped semicolon (\;). The ?exec option should always be the
last option given in a find command.
The find command is great for finding files and
directories but next we'll look at some options for finding other things on the
system.
Dealing with "Permission denied" in find
If you use find a lot (and you probably will) you will
sometimes run into the problem where you get just pages and pages of output like
this:
$ find / -name '*.txt'
find: /var/lib/dav: Permission denied
find: /var/lib/nfs/statd: Permission denied
find: /var/lib/dhcpv6: Permission denied
find: /var/lib/slocate: Permission denied
find: /var/lib/xdm/authdir: Permission denied
find: /var/lib/php/session: Permission denied
find: /var/log/samba: Permission denied
find: /var/log/ppp: Permission denied
find: /var/log/audit: Permission denied
find: /var/log/squid: Permission denied
...
This is find telling you there are certain directories
you don't have permissions to search. This can make it very difficult to find
the useful output of the find as it can be mixed in with the permissions errors.
To ignore these (and any other) errors and just get the
results of what you can find we can use a special redirect at the end of the
command. Redirecting output will be covered in more detail in the chapter on
shell scripting, but suffice it to say that in this command 2>/dev/null is
redirecting the error output to nowhere.
$ find / -name '*.txt' 2>/dev/null
/var/www/icons/small/README.txt
/usr/X11R6/lib/X11/rgb.txt
/usr/X11R6/lib/X11/doc/Xprint_FAQ.txt
/usr/lib/4Suite/tests/Xml/Core/count.txt
...
While it would not be a good idea to redirect the error
output all the time (usually you want to know when something has gone wrong) in
this case of the find command it can be very useful.
Finding a String within a Text File
The grep command can be used to check a file for a
specific string. If grep finds that string it will print the line it found it
on to the screen. Here's an example:
$ cd /etc
$ grep localhost hosts
127.0.0.1 localhost.localdomain localhost
Here we checked the hosts file in the /etc directory for
the word localhost. It was found and grep printed the line it was found on.
grep can be very useful for searching through output for errors or anything else
which typically has a regular pattern.
Finding the Full Directory Path for a Command
The commands we have been executing exist as files
somewhere on the system. The which command is used to find the full path of
these commands. The following examples will show how you can look for the
directory where some commonly used executables are found.
Find the Directory Path for emacs and sort
$ which emacs
/usr/bin/emacs
$ which sort
/bin/sort
The which command takes a single argument of any
command. We have shown above the which command for emacs and sort. The result
indicates where the binary files for those commands exist on the filesystem.
Finding the Location of Program Binary, Source,
Manual Pages for emacs and sort
The whereis command can also be used to locate the
binary file for commands. Additionally, whereis locates the source file and
manual page file the command.
$ whereis emacs
emacs: /usr/bin/emacs /usr/libexec/emacs
/usr/share/emacs /usr/share/man/man1/emacs.1.gz
$ whereis sort
sort: /bin/sort /usr/share/man/man1/sort.1.gz
/usr/share/man/man3/sort.3pm.gz
This is an excerpt from "Easy
Linux Commands" by Linux guru Jon Emmons. You can purchase it for only
$19.95 (30%-off) at
this link.