UNIX-like Tips and Tricks: find command
The find program is a search utility on Unix-like operating systems. It searches through one or more directory trees of a filesystem, locating files based on some user-specified criteria. By default, find command returns all files below the current working directory. Further, find command allows the user to specify an action to be taken on each matched file. In this article I'll show you some tips for using the find command.
To begin, let's look at the basic structure of the find command:
find start_directory test options criteria_to_match action_to_perform
Example:
In the following command, find will search for any file with the "php" extension in the current directory:
# find . -name "*.php" -print
./template/header.php
./template/footer.php
./template/index.php
Unlike many commands, find does not require the -r or -R option in order to descend into the sub directories. It does this by default. However, you may want to limit this behavior. You can do this by using -depth, -maxdepth, and -mindepth options.
The -maxdepth and -mindepth options allow you to specify how far down the directory tree you want find to search. If you want find to look in just one level of the directory, you would use the maxdepth option.
Example:
# find / -maxdepth 5 -name "*log"
NOTE: Doing a find on a large number of files can slow the system down drastically.
1. Using find command to find files based on their size
The following command will show you files with zero size:
# find /dir/path -type f -size 0
Multiple options can be placed in sequence with AND and OR boolean options (and parenthesis). For example, to find all files containing "code" in the name that are newer than four days and are larger than 20K, run this command:
# find . -name "*code*" -size +20480 -mtime -4
2. Using find command with timestamps
The find command has several options that are used to search for files based on system's time stamps.
These time stamps are: mtime, atime and ctime.
- mtime—the time that the contents of a file were last modified
- atime—the time that a file was read or accessed
- ctime—the time that a file's status was changed
Each of these time options needs to be used with a value n, which is specified as:
- -n returns less than n
- +n returns greater than n
- n returns exactly n matches
Example:
The following command will find all the files modified within the last two hours:
# find . -mtime -2
./templates/index.php
./templates/footer.php
Running the same command with 2 instead of -2 finds all the files that were modified exactly two hours ago:
# find . -mtime 2
The above command may not yield any results, because it asks for an exact match. The following command looks for the files that were modified more than two hours ago:
# find . -mtime +2
By default, -mtime, -atime, and -ctime refer to the last 24 hours. If, however, they are preceded by the daystart option, the 24-hour period will begin with the start of the current day. You can also look for time stamps that have changed in less than an hour using mmin, amin, and cmin.
You can also find files that have been modified or accessed in comparison to a specific file with the options -newer, -anewer, and –cnewer.
This is similar to -mtime, -atime, and –ctime:
- -newer refers to files whose contents have been modified more recently
- -anewer refers to files that have been read more recently
- -cnewer refers to files whose status has changed more recently
To find all the files in the current directory that have been edited since the last example.conf file, run this command:
# find . -newer example.conf
The following command will delete files older than 7 days:
# find /path/to/files -mtime +7 -exec rm {} \;
NOTE: Locating a file with the find command itself changes that file's access time as part of its metadata.
3. Finding files by Permission and Ownership
The find command can be used for monitoring the security of your system. You can look for files with wide open permissions:
# find . -type f -perm 777 -exec ls -l {} \;
or
# find . -type f -perm a=rwx -exec ls -l {} \;
-rwxrwxrwx 1 adrian users 92 Apr 29 19:28 ./testfile.txt
In the above and the following commands in this section, we are using the -exec ls -l action so you can see the actual permissions of the files returned. The command will find files that are writable by both the "other" and the group:
# find example_dir -type f -perm -ug=rw -exec ls -l {} \; 2>/dev/null
or
# find example_dir -type f -perm -220 -exec ls -l {} \; 2>/dev/null
-rw-rw-rw- 1 adrian users 2398 Mar 11 2010 example_dir/file.css
-rw-rw-rw- 1 adrian users 1017 Apr 29 2010 example_dir/files/readme.txt
This next command will find files that are writable by the user, the group, or both:
# find example_dir -type f -perm /ug=rw -exec ls -l {} \; 2>/dev/null, or,
# find example_dir -type f -perm /220 -exec ls -l {} \; 2>/dev/null
-rw-r--r-- 1 adrian users 9147 May 3 2010 example_dir/examples.zip
-rw-rw-rw- 1 adrian users 4303 Apr 29 19:08 example_dir/examples.txt
To find all files on your system that are world writable, use the following command:
# find / -wholename '/proc' -prune -o -type f -perm -0002 -exec ls -l {} \;
-rw-rw-rw- 1 adrian users 9274 Mar 17 2010 /home/adrian/projects/doc/style.css
-rw-rw-rw- 1 adrian users 8276 Apr 29 2010 /home/adrian/doc/readme.txt
Sysadmins frequently use find command to search for regular files of specific users or groups using the name or ID of that user or group:
# find / -type f -user adrian -exec ls -l {} \;
-rw-r--r-- 1 adrian users 82 Mar 1 19:27 /home/adrian/public_html/index.php
-rw-r--r-- 1 adrian users 925 Apr 28 22:08 /home/adrian/.profile
You can also use find to look for a file by group:
# find / -type f -group users
# find / -type d -gid 100
This command will show you a list of directories owned by group ID 100. To find the appropriate gid or uid, you can run the cat command on the /etc/group or /etc/passwd file.
Beyond finding files of specific known users and groups, you may also find it useful to look for files lacking either of these:
# find / -nouser -o -nogroup
The SGID and SUID are special access right flags that can be assigned to files and directories on a UNIX-like operating system. They are set to allow ordinary users on a computer system access to execute binary executables with temporarily elevated privileges.
# find / \( -perm -2000 -o -perm -4000 \) -ls
142783 12 -rwsr-xr-x 1 root root 9071 Apr 16 2009 /usr/bin/rsh
142785 12 -rwxr-sr-x 1 root tty 10233 Apr 15 2009 /usr/bin/ping
In the above command, you can see the use of escaped parentheses. You can also see the differences in permissions.
Print This Post