GNU vs BSD find: Differences on macOS Runners
Linux runners ship GNU find while macOS runners ship BSD find, and several predicates differ between them.
A find one-liner that works on Linux can fail on a macOS runner. Knowing which predicates are GNU-only saves a cross-platform debugging session.
What it does
GNU find (the findutils on most Linux images) and BSD find (the system find on macOS) share core predicates like -name, -type, -size, -mtime, and -delete, but diverge on extensions. -printf and -regextype are GNU only; BSD uses -E for extended regex. Option-order strictness also differs.
Common usage
# portable across both:
find . -type f -name '*.log' -delete
# GNU only:
find . -type f -printf '%s %p\n'
# BSD/macOS extended regex:
find -E . -regex '.*\.(js|ts)$'Options
| Feature | GNU vs BSD |
|---|---|
| -printf | GNU only; BSD has no equivalent |
| -regextype | GNU only; BSD uses find -E for extended regex |
| -iname / -delete / -print0 | Both support these |
| -maxdepth / -mindepth | Both, though GNU warns on placement |
| gfind | GNU find on macOS via Homebrew coreutils/findutils |
In CI
For matrices that include macOS, stick to the common subset: -name, -iname, -type, -size, -mtime, -newer, -delete, -print0, -exec. Avoid -printf and -regextype, or install GNU find with brew and call gfind. Test the find lines on both runner OSes, not just Linux.
Common errors in CI
"find: unknown predicate '-printf'" and "find: -regextype: unknown primary or operator" both mean a GNU-only predicate ran on BSD/macOS find. Use the portable subset, gfind, or an -exec fallback. Option-order warnings about -maxdepth are GNU specific; BSD is more lenient there.