The find command is an extremely useful utility to find files that fulfill some criteria. The whole range of options can be learnt by reading the man page for find, but some of the most useful options are laid out below:
# find / -amin -30 → files accessed less than 30 minutes ago
# find / -atime +1 → files accessed more than one day ago (before 00:00 of yesterday!)
# find / -cmin +60 → files changed more than 60 minutes ago
# find / -ctime -2 → files changed less than 2 days ago (after 00:00 of 2 days ago)
# find / -mmin -5 → files whose data was modified less than 5 minutes ago
# find / -mtime +1 → files whose data was modified before yesterday
# find / -empty → files empty (regular files or directories)
# find / -executable → files that are executable (ACL aware unlike –perm !)
# find / -readable → files that are readable (ACL aware unlike –perm !)
# find / -writable → files that are writable (ACL aware unlike –perm !)
# find / -fstype xfs → files that reside on xfs file systems
# find / -user oracle → files whose owner is oracle
# find / -group dba → files whose group is dba
# find / -uid 501 → files whose UID is 501
# find / -gid 501 → files whose GID is 501
# find / -perm 1750 → files whose permissions match exactly 1750
# find / -perm -777 → files whose permissions match exactly 750 ignoring sticky bits
# find / -perm +111 → files that are executable by either user, group or other
# find / -size +1M → files larger than 1Mb ( b block, c byte, k kbyte, M mbyte, G Gbyte)
# find / -nouser → files whose UID does not match any known user (user deleted?)
# find / -nogroup → files whose GID does not match any known group (deleted group?)
# find / -type s → files of socket type (b=block, c=character, d=directory, p=pipe,
. f=regular file, l=symbolic link, s=socket, D=Solaris door)
# find / -name “sqlplus*” → files whose name match the simple pattern sqlplus*
# find / -iname “sqlplus*” → same as above but caseinsensitive
# find / -inum 1234565 → files whose inode is 123456
# find / -regex “.123[45]?*” → files whose name match the given regex
# find / -samefile file123 → files that are hard linked to file123
# find / -wholename “./bin/sqlplus*” → files whose whole path match the given pattern
# find / -iwholename “./bin/sqlplus*” → same as above but case insensitive
# find / -context httpd_sys_content_t → files with the given SELinux context
# find / -samefile /tmp/123.txt → looks for files that refer to the same inode as 123.txt
In the examples above we have seen how to look for files that fit certain criteria. But the find command also allows us to perform some actions with those files…
# find / -nouser -delete → finds files whose UID is unknown and deletes them
# find / -nouser -ok rm {} ; → same as above but prompting before each deletion
# find / -nogroup | xargs -0r /bin/rm -rf → same as the two above but the old fashioned way
# find / -uid 1001 -type f -execdir ls -l {} ; → “ls -l” on regular files owned by uid 1001
# find / -nouser -ls → finds files whose UID is unknown and lists them
The find command is the search tool used most often in Linux to look for files and directories fitting a certain criteria. However, if the searches are to be conducted on large file systems, some searches might take a considerable time and I/O.
In a default installation of RHEL7 there is a daily scheduled job called mlocate which updates a database (usually in /var/lib/mlocate/mlocate.db) that contains an indexed entry for every directory and file in the system. The main objective of this database is to speed up searches for files/directories avoiding the usually slow find command. We can manually update that database after modifying the contents of the system with:
# /etc/cron.daily/mlocate → best way to do it
# updatedb → alternative way
The configuration script for updatedb is non-surprisingly /etc/updatedb.conf:
# cat /etc/updatedb.conf
PRUNE_BIND_MOUNTS = “yes”
PRUNEFS = “9p afs anon_inodefs auto autofs bdev binfmt_misc cgroup cifs coda configfs cpuset debugfs devpts ecryptfs exofs fuse fuse.sshfs fusectl gfs gfs2 gpfs hugetlbfs inotifyfs iso9660 jffs2 lustre mqueue ncpfs nfs nfs4 nfsd pipefs proc ramfs rootfs rpc_pipefs securityfs selinuxfs sfs sockfs sysfs tmpfs ubifs udf usbfs ceph fuse.ceph”
PRUNENAMES = “.git .hg .svn .bzr .arch-ids {arch} CVS”
PRUNEPATHS = “/afs /media /mnt /net /sfs /tmp /udev /var/cache/ccache /var/lib/yum/yumdb /var/lib/dnf/yumdb /var/spool/cups /var/spool/squid /var/tmp /var/lib/ceph”
The locate command can be used with straight-names, globbing or regex:
# locate passwd → shows files/directories with “passwd” anywhere in the fullpath
# locate *passwd → shows files/directories that end with “passwd”
# locate --
regex “.*documentation.*pdf” → shows matches fitting regex
There are 4 more commands to do different kinds of searches.
The first one of them is findfs which, as its name implies, is meant to look for filesystems using their labels and UUIDs:
root:/tmp> findfs LABEL=”TMP”
/dev/sdb1
.
root:/tmp> findfs UUID=”f4934d4f255a4db9ae1f495cb35576d4″
/dev/mapper/vgvar
This command achieves the same result as the following command in a much neater way:
root:/tmp> blkid | grep f4934d4f255a4db9ae1f495cb35576d4 | cut -d “:” -f1
/dev/mapper/vgvar
We can use mountpoint to check whether or not a certain directory is a mountpoint as well as to obtain the major/minor number of the devices underneath:
root:/home/marc> mountpoint /home
/home is a mountpoint
.
root:/home/marc> mountpoint /home/marc
/home/marc is not a mountpoint
.
root:/home/marc> mountpoint -x /dev/sda
8:0
.
root:/home/marc> mountpoint -x /dev/sda1
8:1
.
root:/home/marc> mountpoint -d /var
253:11
The “-x” flag shows us the major/minor device number of the given device. The “-d” flag does the same but the argument is meant to be a directory.
Another useful command is findmnt which does a similar job as tree but for filesystems:
root:/home/marc> findmnt → show all filesystems in tree format
TARGET SOURCE FSTYPE OPTIONS
/ /dev/mapper/vgroot xfs rw,relatime,seclabel,attr2,inode64,noquota
├─ /sys sysfs sysfs rw,nosuid,nodev,noexec,relatime,seclabel
│ ├─ /sys/kernel/security securityfs securityfs rw,nosuid,nodev,noexec,relatime
│ ├─ /sys/fs/cgroup tmpfs tmpfs ro,nosuid,nodev,noexec,seclabel,mode=755
│ │ ├─ /sys/fs/cgroup/systemd cgroup cgroup rw,nosuid,nodev,noexec,relatime,xattr,…
│ │ ├─ /sys/fs/cgroup/cpuset cgroup cgroup rw,nosuid,nodev,noexec,relatime,cpuset
│ │ ├─ /sys/fs/cgroup/cpu,cpuacct cgroup cgroup rw,nosuid,nodev,noexec,relatime,cpu,cpuacct
│ │ ├─ /sys/fs/cgroup/blkio cgroup cgroup rw,nosuid,nodev,noexec,relatime,blkio
│ │ ├─ /sys/fs/cgroup/memory cgroup cgroup rw,nosuid,nodev,noexec,relatime,memory
│ │ ├─ /sys/fs/cgroup/devices cgroup cgroup rw,nosuid,nodev,noexec,relatime,devices
[…]
.
root:/home/marc> findmnt -t xfs → show only xfs filesystems (or ext3, ext4, etc)
TARGET SOURCE FSTYPE OPTIONS
/ /dev/mapper/vgroot xfs rw,relatime,seclabel,attr2,inode64,noquota
├─ /tmp/photos /dev/mapper/vgdataphotos xfs rw,relatime,seclabel,attr2,inode64,sunit=2048,…
├─ /home /dev/mapper/vghome xfs rw,relatime,seclabel,attr2,inode64,noquota
│ ├─ /home/marc/software /dev/mapper/vgdatasoftware xfs rw,relatime,seclabel,attr2,inode64,sunit=2048,…
[…]
.
root:/home/marc> findmnt --
target /home -R -o TARGET,SOURCE,OPTIONS
TARGET SOURCE OPTIONS
/home /dev/mapper/vghome rw,relatime,seclabel,attr2,inode64,noquota
├─ /home/marc/companies /dev/mapper/vgdatacompanies rw,relatime,seclabel,attr2,inode64,sunit=128,…
├─ /home/marc/software /dev/mapper/vgdatasoftware rw,relatime,seclabel,attr2,inode64,sunit=2048,…
├─ /home/marc/personal /dev/mapper/vgdatapersonal rw,relatime,seclabel,attr2,inode64,sunit=2048,…
├─ /home/marc/photos /dev/mapper/vgdataphotos rw,relatime,seclabel,attr2,inode64,sunit=2048,…
[…]
This last example of findmnt shows all the mountpoints hanging from “/home”, recursively, and limits the output to the 3 fields specified with the “-o” flag.
We can also use findmnt to monitor mounts, remounts, umounts and moves:
root:/home/marc> findmnt --
poll
ACTION TARGET SOURCE FSTYPE OPTIONS
mount /tmp/photos /dev/mapper/vgdataphotos xfs rw,relatime,seclabel,attr2,inode64,sunit=2048,…
ACTION TARGET SOURCE FSTYPE OPTIONS
umount /tmp/photos /dev/mapper/vgdataphotos xfs rw,relatime,seclabel,attr2,inode64,sunit=2048,…
The last command we will cover in this section is namei. This utility follows each pathname until and endpoint is found and is especially useful to follow long, erroneous or circular symbolic links:
root:/home/marc> ln -s /usr/bin/tree /tmp/tree
root:/home/marc> ln -s /tmp/tree /var/tmp/tree
root:/home/marc> ln -s /var/tmp/tree /var/run/tree
root:/home/marc> namei /var/run/tree
f: /var/run/tree
.d /
.d var
.l run -> ../run
. d ..
. d run
.l tree -> /var/tmp/tree
. d /
. d var
. d tmp
. l tree -> /tmp/tree
. d /
. d tmp
. l tree > /usr/bin/tree
. d /
. d usr
. d bin
. – tree
.
root:/home/marc> namei /var/run/tree -l
f: /var/run/tree
dr-xr-xr-x root root /
drwxr-xr-x root root var
lrwxrwxrwx root root run -> ../run
dr-xr-xr-x root root ..
drwxr-xr-x root root run
lrwxrwxrwx root root tree -> /var/tmp/tree
dr-xr-xr-x root root /
drwxr-xr-x root root var
drwxrwxrwt root root tmp
lrwxrwxrwx root root tree -> /tmp/tree
dr-xr-xr-x root root /
drwxrwxrwt root root tmp
lrwxrwxrwx root root tree -> /usr/bin/tree
dr-xr-xr-x root root /
drwxr-xr-x root root usr
dr-xr-xr-x root root bin
-rwxr-xr-x root root tree