From cc57ee1cafa9a55eaac193f07cc39edeee108a2a Mon Sep 17 00:00:00 2001 From: RadinPirouz <75082987+RadinPirouz@users.noreply.github.com> Date: Sun, 9 Nov 2025 12:45:21 +0330 Subject: [PATCH] added find command --- Linux/Basic Administration/29-find.md | 313 ++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 Linux/Basic Administration/29-find.md diff --git a/Linux/Basic Administration/29-find.md b/Linux/Basic Administration/29-find.md new file mode 100644 index 0000000..29ab26c --- /dev/null +++ b/Linux/Basic Administration/29-find.md @@ -0,0 +1,313 @@ +# `find` — quick reference & practical documentation + +This is a compact, practical reference for the Unix/Linux `find` command aimed at DevOps engineers and system administrators. It covers common options, tests, actions, operators, examples (safe and practical) and performance tips. + +--- + +# Synopsis + +``` +find [path...] [expression] +``` + +If no `path` is given, `find` searches the current directory (`.`). `expression` is evaluated left-to-right and can contain tests, actions and operators. + +--- + +# Basic behaviour + +* `find` walks directory trees recursively by default. +* An *expression* evaluates to true/false; when true, the default action `-print` (or whatever action is specified) is executed. +* You can control traversal order with `-depth` and `-maxdepth`/`-mindepth`. +* `-prune` prevents descending into directories. + +--- + +# Common options and switches + +* `-H` : follow symbolic links specified on the command line. +* `-L` : follow all symbolic links. +* `-P` : never follow symbolic links (default). +* `-xdev` : don't descend into directories on other filesystems (useful when walking `/`). +* `-mindepth N` : do not apply tests/actions to files at depth < N. +* `-maxdepth N` : do not descend past depth N. +* `-depth` : process directory contents before the directory itself (useful for safe deletes). +* `-mount` : same as `-xdev` (GNU find). + +--- + +# Common tests (predicates) + +* `-name pattern` : match basename with shell globbing (case-sensitive). Pattern uses shell wildcards (`*`, `?`, `[]`). +* `-iname pattern` : case-insensitive `-name`. +* `-path pattern` : match the whole path (slash-separated) with shell globbing. +* `-ipath pattern` : case-insensitive `-path`. +* `-regex pattern` : match full path with regular expression (syntax differs by `find` implementation; GNU `find` defaults to Emacs regex). +* `-type c` : file type; `f` = regular file, `d` = directory, `l` = symlink, `c` = character device, `b` = block device, `p` = FIFO, `s` = socket. +* `-perm mode` : file permission test. Modes: + + * octal: `-perm 0644` (exact) + * symbolic: `-perm -u=w` (any of the bits), `-perm /u=w` (any), `-perm -0644` (all bits set) + * GNU `find` also accepts `/mode` to mean "any of the bits". +* `-user name` / `-uid uid` : owner. +* `-group name` / `-gid gid` : group. +* `-size n[cwbk]` : file size; default 512-byte blocks for some `find` versions; most use 1K blocks for `k`. GNU `find` suffixes: + + * `c` = bytes + * `k` = kilobytes + * `M` = megabytes + * `G` = gigabytes + * `+n` = greater than n, `-n` = less than n, `n` = exactly n +* `-mtime n` / `-atime n` / `-ctime n` : modified / accessed / changed time in 24-hour periods; `-mtime +7` older than 7 days, `-mtime -7` less than 7 days, `-mtime 7` exactly 7. +* `-mmin n`, `-amin n`, `-cmin n` : minutes. +* `-newer file` : newer than file (can be combined with `!` to negate). +* `-empty` : empty file or directory. +* `-links n` : number of hard links. +* `-readable` / `-writable` / `-executable` : access checks from running user perspective. + +--- + +# Common actions + +* `-print` : print path (often default; some implementations require explicit `-print` with complex expressions). +* `-print0` : print paths separated by NUL (safe with whitespace/newlines). +* `-ls` : list file using `ls -dils` style. +* `-exec command {} \;` : run `command` once per matched file. `{}` is replaced by the current path. The `\;` terminator must be escaped or quoted. +* `-exec command {} +` : optimized form; appends multiple matches to command arguments like `xargs` (more efficient). +* `-ok command {} \;` : like `-exec` but prompts the user before each execution. +* `-delete` : delete matched files/directories (be careful; obeys ordering and `-depth`). +* `-prune` : exclude directory from descent (returns true; often used with `-o`). +* `-quit` : stop after first match (very efficient when used with `-print`). +* `-mindepth N`, `-maxdepth N` already described; they behave like tests. + +--- + +# Operator precedence (GNU `find` style) + +* Parentheses `(` `)` group expressions. They must be escaped or quoted: `\( ... \)` or `'(' ... ')'`. +* `!` or `-not` : logical NOT (unary). +* `-a` or implicit concatenation : logical AND. +* `-o` or `-or` : logical OR. +* Evaluation is left-to-right; `-a` has higher precedence than `-o`. Use parentheses to be explicit. +* Common pitfall: mixing `-prune` and `-o` requires careful grouping: + Example pattern to exclude `dir`: + + ``` + find . -path ./dir -prune -o -print + ``` + + This means: if path is `./dir` prune it (and `-prune` returns true) otherwise (`-o`) `-print`. + +--- + +# Typical practical examples + +Search examples assume `bash` shell; escape parentheses and semicolons as needed. + +1. Find files by name (case-sensitive) + +``` +find /var/log -type f -name "syslog*" +``` + +2. Case-insensitive: + +``` +find /home -type f -iname "*.jpg" +``` + +3. Find empty directories: + +``` +find /path -type d -empty +``` + +4. Delete `*.tmp` files safely (print first, then delete) + +``` +find /data -type f -name "*.tmp" -print +find /data -type f -name "*.tmp" -delete +``` + +Or safer with confirmation: + +``` +find /data -type f -name "*.tmp" -ok rm {} \; +``` + +5. Find and remove files older than 30 days (safe: use `-print` first) + +``` +find /var/log -type f -mtime +30 -print +find /var/log -type f -mtime +30 -exec rm -- {} + +``` + +Prefer `-exec ... +` over `-exec ... \;` for efficiency. + +6. Remove directories older than 30 days (use `-depth` to ensure files inside are removed first) + +``` +find /tmp -depth -type d -mtime +30 -exec rm -rf -- {} + +``` + +`-delete` may also be used but beware of ordering; `-depth` ensures children processed before parent. + +7. Find files with spaces and handle them safely: + +``` +find /srv -type f -name "*.conf" -print0 | xargs -0 grep -H "pattern" +``` + +8. Find files larger than 100 MiB: + +``` +find / -type f -size +100M -print +``` + +9. Find files newer than a reference file: + +``` +find /web -type f -newer /tmp/deploy_marker -print +``` + +10. Find and run a command on many files (batching): + +``` +find /data -type f -name "*.log" -exec gzip -- {} + +``` + +11. Exclude a directory (`dir_to_skip`) while listing everything else: + +``` +find . -path "./dir_to_skip" -prune -o -print +``` + +12. Only search one level (non-recursive): + +``` +find . -maxdepth 1 -type f -print +``` + +13. Find broken symlinks: + +``` +find / -xtype l -print +``` + +Note: `-xtype` tests the target type; `-L` changes behavior of `-type`. + +14. Use `-printf` to customize output (GNU find): + +``` +find . -type f -printf "%p\t%k KB\t%TY-%Tm-%Td %TH:%TM:%TS\n" +``` + +`-printf` supports format sequences (`%p` path, `%s` bytes, `%k` KB blocks, `%TY` year, ...). Exact spec depends on implementation (GNU has extensive options). + +15. Stop at first match (fast): + +``` +find /usr -type f -name "passwd" -print -quit +``` + +16. Find files modified within last 15 minutes: + +``` +find /var -type f -mmin -15 +``` + +--- + +# Safe deletion checklist + +* Always `-print` or `-ls` first to verify matches. +* Prefer `-exec rm -- {} +` or use `-delete` with `-depth` if required. +* Watch out for `-maxdepth`/`-mindepth` to avoid accidental top-level deletions. +* Use `-print0` + `xargs -0` when passing to other utilities. +* Consider using `-ok` for destructive changes in interactive contexts. + +--- + +# Performance & scalability tips + +* Limit scope: pass explicit starting paths instead of `.` or `/` when possible. +* Use `-maxdepth` and `-mindepth` to reduce traversal. +* Use `-xdev` to avoid crossing filesystem boundaries (speeds up root scans). +* Combine fast tests early (e.g., `-type f -name "*.log"` rather than `-name` alone) because find evaluates left-to-right; short-circuiting happens when possible. +* Prefer `-exec ... +` to `-exec ... \;` to reduce process spawn overhead. +* Use `-prune` to skip large tree branches that aren’t needed. +* On very large trees consider tools optimized for indexing (e.g., `locate` / `mlocate`, `fd`, or ripgrep for content search). `find` is always consistent but traverses the disk each run. + +--- + +# Portability notes + +* Behavior, available tests/actions and argument formats vary slightly between implementations (GNU `find` vs BSD `find` vs BusyBox). Examples above assume GNU `find` when using `-printf`, `-delete`, `-quit` or suffixes like `M`/`G` for sizes. +* When writing scripts for mixed environments, try to stick to portable tests: `-name`, `-type`, `-mtime`, `-print`, `-exec ... \;`. Check `/usr/bin/find --version` or `man find` on target hosts. + +--- + +# Gotchas & common pitfalls + +* Shell globbing vs `find` globbing: `-name "*.txt"` is matched by `find` and must be quoted to prevent shell expansion. +* `-perm` exact vs any-bit semantics differ across versions; test on target system. +* `-regex` matches the whole path, not just basename; regex dialect differs (use `-regextype posix-extended` on GNU `find` to set type). +* `-delete` will fail if used before tests that select children (order matters). Use `-depth` or test ordering appropriately. +* Beware of running `find` as root with `-exec rm -rf {}` — very dangerous if expression is wrong. Always verify output. +* `-maxdepth`/`-mindepth` may not be supported in very old `find` implementations. + +--- + +# Exit status + +* `0` : at least one match and command completed successfully. +* `1` : no matches were found (behavior can vary). +* `>1` : an error occurred (e.g., permission errors or malformed expression). + Note: exact meanings can depend on implementation. + +--- + +# Useful combinations + +* Find files and preserve relative paths for tar: + +``` +cd /path && find . -type f -name "*.conf" -print0 | tar --null -T - -czf confs.tar.gz +``` + +* Find and change ownership or permissions: + +``` +find /srv/www -type f -name "*.php" -exec chown www-data:www-data {} + +find /srv/www -type d -exec chmod 755 {} + +``` + +* Search content in matched files: + +``` +find /app -type f -name "*.py" -print0 | xargs -0 grep -n "TODO" +``` + +--- + +# Related commands/tools + +* `locate` / `mlocate` : fast filename lookup (uses database). +* `fd` : simpler, faster user-friendly alternative to `find` (not always installed). +* `xargs` : pass batches of arguments to commands (careful with spaces; use `-print0` + `xargs -0`). +* `stat` : detailed file metadata for a single file. +* `rm`, `tar`, `gzip`, `chown`, `chmod`, `rsync` : commonly used alongside `find`. + +--- + +# Quick cheatsheet (most-used patterns) + +* Find files by name: `find /path -type f -name "pattern"` +* Case-insensitive: `-iname` +* Size bigger than 100M: `-size +100M` +* Modified > 7 days: `-mtime +7` +* Delete old files: `find /dir -type f -mtime +30 -exec rm -- {} +` +* Print NUL-separated: `-print0` +* Safe prune: `find . -path ./skip -prune -o -print` +* Batch exec: `-exec cmd {} +` +* Stop on first: `-print -quit`