search

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 case­insensitive
# 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="f4934d4f­255a­4db9­ae1f­495cb35576d4"
/dev/mapper/vgvar

This command achieves the same result as the following command in a much neater way:

root:/tmp> blkid | grep f4934d4f­255a­4db9­ae1f­495cb35576d4 | cut ­-d ":" -­f1
/dev/mapper/vg­var

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/vg­root  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/vg­root         xfs     rw,relatime,seclabel,attr2,inode64,noquota
├─ /tmp/photos             /dev/mapper/vgdata­photos   xfs     rw,relatime,seclabel,attr2,inode64,sunit=2048,...
├─ /home                   /dev/mapper/vg­home         xfs     rw,relatime,seclabel,attr2,inode64,noquota
│ ├─ /home/marc/software   /dev/mapper/vgdata­software 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/vg­home           rw,relatime,seclabel,attr2,inode64,noquota
├─ /home/marc/companies   /dev/mapper/vgdata­companies  rw,relatime,seclabel,attr2,inode64,sunit=128,...
├─ /home/marc/software    /dev/mapper/vgdata­software   rw,relatime,seclabel,attr2,inode64,sunit=2048,...
├─ /home/marc/personal    /dev/mapper/vgdata­personal   rw,relatime,seclabel,attr2,inode64,sunit=2048,...
├─ /home/marc/photos      /dev/mapper/vgdata­photos     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/vgdata­photos  xfs     rw,relatime,seclabel,attr2,inode64,sunit=2048,...
ACTION   TARGET       SOURCE                    FSTYPE  OPTIONS
umount   /tmp/photos  /dev/mapper/vgdata­photos  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

 

<< query commands             view and create commands >>