| title | Linux Command Tutorial: find | ||||
|---|---|---|---|---|---|
| date | 2026-09-12 00:00:00 +0000 | ||||
| categories |
|
||||
| tags |
|
||||
| draft | false | ||||
| slug | linux-find-tutorial | ||||
| description | Authoritative reference tutorial for find (GNU Findutils), detailing expression predicates, null-delimited output (-print0), execdir safety, and POSIX portability. | ||||
| upstream_suite | gnu-findutils | ||||
| upstream_version | GNU Findutils 4.10 | ||||
| posix_standard | POSIX.1-2024 | ||||
| research_date | 2026-09-12 |
The Linux Command Tutorial series provides rigorous, upstream-verified references for essential system commands across Linux distributions and UNIX-like environments. Each article focuses on a single executable, combining exhaustive option documentation, verified real-world examples, security boundaries, and best practices directly derived from official source documentation and POSIX standards.
Upstream: GNU Findutils 4.10 | POSIX: POSIX.1-2024 (with GNU extensions) | Safety Tier: safe-read-only | Scope: filesystem-search
find searches directory trees recursively, evaluating boolean expressions composed of tests, actions, and global options against each visited file and directory.
- Upstream Project & Provenance: Developed and maintained under GNU Findutils (
findutils). - Portability & Standards Baseline: Standardized in IEEE Std 1003.1-2024 (POSIX.1-2024). GNU
findintroduces crucial security and efficiency features, including-print0,-execdir,-delete,-regextype, and-daystart. - Target Research Implementation: Audited against GNU Findutils 4.10 (
find(1)). - Applicability & Lifecycle: The foundational tool for filesystem searching, selective cleanup, and pipeline generation.
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]findevaluates an expression composed of:- Operators:
-and(default between adjacent tests),-or(-o),not(!). - Tests: Criteria that return true or false (
-name,-type,-mtime,-size,-perm). - Actions: Side-effect operations (
-print,-print0,-delete,-exec,-execdir).
- Operators:
- Short-Circuit Evaluation: Like C boolean operators, if the left side of an
-andexpression evaluates to false, the right side is never evaluated. Therefore, actions like-deleteor-execshould always appear after filtering tests.
| Predicate | Description | POSIX Defined |
|---|---|---|
-name pattern |
Base of file name matches shell pattern. | Yes |
-iname pattern |
Like -name, but the match is case-insensitive. |
No |
-type c |
File is of type c: f (regular), d (directory), l (symlink), s (socket). |
Yes |
-mtime n |
File data was modified n*24 hours ago (+n greater than, -n less than). |
Yes |
-size n[cwbkMG] |
File uses n units of space (e.g. +100M). |
Yes |
-perm mode |
File's permission bits are set exactly to mode (or matched with / or -). |
Yes |
-empty |
File is empty and is either a regular file or a directory. | No |
| Action | Description | Upstream Note |
|---|---|---|
-print |
Print the full file name, followed by a newline. | Default action if no other action given |
-print0 |
Print the full file name, followed by a null character (\0). |
Crucial for safe piping to xargs -0 |
-exec cmd {} ; |
Execute cmd on each file individually (spawns 1 process per file). |
Inefficient for large sets |
-exec cmd {} + |
Execute cmd on multiple files simultaneously (batches arguments). |
High performance |
-execdir cmd {} + |
Execute cmd from the subdirectory containing the matched file. |
Protects against race attacks |
-delete |
Delete files; turns on -depth automatically. |
Direct unlink |
| Operation | Command | Notes |
|---|---|---|
| Find files by name | find /path -name "*.log" |
Case-sensitive pattern match |
| Find files ignoring case | find /path -iname "*.conf" |
Case-insensitive pattern match |
| Find regular files only | find /path -type f |
Excludes directories, symlinks, sockets |
| Find directories only | find /path -type d |
Recursively finds subdirectories |
| Find files modified in last 7 days | find /path -type f -mtime -7 |
Relative time in 24-hour periods |
| Find files larger than 100MB | find /path -type f -size +100M |
Searches by exact byte or unit threshold |
| Batch execute safely | find /path -type f -name "*.tmp" -print0 | xargs -0 rm -f |
Null-delimited pipeline safe against special characters |
find /etc -name "*.conf"find /var/log -type dPurging temporary files safely, even if filenames contain spaces or newlines:
find /tmp/app_cache -type f -name "*.tmp" -print0 | xargs -0 rm -f- Technical Analysis:
-print0uses the null byte (\0) as the delimiter. Because UNIX filenames cannot legally contain\0, this guarantees immunity to argument splitting.
find /var -type f -size +500M -exec ls -lh {} +- Technical Analysis:
-size +500Mtests for sizes strictly greater than 500 megabytes;-exec ... +batches multiple files into a singlelsinvocation, minimizing process spawning.
find /home/admin/project -type f -mtime -1Locating files that any local user can modify:
find /var/www -type f -perm -0002 -ls-perm -0002checks if the "other" write bit (w) is asserted.
When running commands on files located in world-writable or shared directories:
find /tmp/uploads -type f -name "*.sh" -execdir chmod 644 {} +- Technical Analysis:
-execdirchanges the working directory to the parent directory of the file before invoking the command, and passes./filename. This completely eliminates TOCTOU (Time-Of-Check to Time-Of-Use) race conditions where an attacker substitutes a path component with a symlink whilefindis executing.
Skipping entire directory trees (like .git or node_modules) to accelerate traversal:
find . \( -name ".git" -o -name "node_modules" \) -prune -o -type f -name "*.js" -print- When
.gitis encountered,-prunetellsfindnot to descend into it, drastically reducing disk I/O.
| Exit Code | Meaning |
|---|---|
0 |
All files were traversed and all actions succeeded. |
>0 |
An error occurred (permission denied on directory, -exec command failed, invalid syntax). |
Caution
Catastrophic -delete Order Hazard: find processes predicates sequentially from left to right using short-circuit evaluation. Putting -delete before filter criteria (e.g., find /var/tmp -delete -name "*.log") evaluates -delete on every file first, wiping out the entire directory!
Always place -delete as the final action:
find /var/tmp -type f -name "*.log" -delete- Always Use
-print0When Piping into Downstream Commands:- Guidance: Pair
find -print0withxargs -0orwhile IFS= read -r -d '' file. - Authoritative Justification: GNU documentation notes that newline-delimited streams break on filenames containing spaces, tabs, or newlines.
- Guidance: Pair
- Use
-exec ... +Instead of-exec ... \;:- Guidance: Terminate
-execwith+rather than\;whenever possible. - Authoritative Justification: Passes hundreds of files per process invocation, reducing CPU overhead by up to 98%.
- Guidance: Terminate
- Use
-execdirin Shared and Untrusted Directories:- Guidance: Replace
-execwith-execdiron/tmpor user-writable uploads. - Authoritative Justification: Upstream Findutils security advisories warn that standard
-execis vulnerable to symlink substitution attacks during path traversal.
- Guidance: Replace
- GNU Findutils find Manual: https://www.gnu.org/software/findutils/manual/html_node/find_html/index.html
- POSIX.1-2024 find Specification: The Open Group Base Specifications Issue 8. https://pubs.opengroup.org/onlinepubs/9799919799/utilities/find.html