From aa6797db463b5143c5ca05bb5e90b05d2f72122a Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 19 Apr 2022 11:30:47 -0400 Subject: docs: Move some documentation into a subfolder --- CONTRIBUTING.md | 167 ----------- Makefile | 2 +- RELEASES.md | 655 ----------------------------------------- bfs.1 | 811 --------------------------------------------------- docs/CHANGELOG.md | 655 +++++++++++++++++++++++++++++++++++++++++ docs/CONTRIBUTING.md | 167 +++++++++++ docs/bfs.1 | 811 +++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 1634 insertions(+), 1634 deletions(-) delete mode 100644 CONTRIBUTING.md delete mode 100644 RELEASES.md delete mode 100644 bfs.1 create mode 100644 docs/CHANGELOG.md create mode 100644 docs/CONTRIBUTING.md create mode 100644 docs/bfs.1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 28bfac2..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,167 +0,0 @@ -Contributing -============ - -License -------- - -`bfs` is licensed under the [Zero-Clause BSD License](https://opensource.org/licenses/0BSD), a maximally permissive license. -Contributions must use the same license. - - -Building --------- - -`bfs` uses [GNU Make](https://www.gnu.org/software/make/) as its build system. -A simple invocation of - - $ make - -should build `bfs` successfully, with no additional steps necessary. -As usual with `make`, you can run a [parallel build](https://www.gnu.org/software/make/manual/html_node/Parallel.html) with `-j`. -For example, to use all your cores, run `make -j$(nproc)`. - -### Targets - -| Command | Description | -|------------------|---------------------------------------------------------------| -| `make` | Builds just the `bfs` binary | -| `make all` | Builds everything, including the tests (but doesn't run them) | -| `make check` | Builds everything, and runs the tests | -| `make install` | Installs `bfs` (with man page, shell completions, etc.) | -| `make uninstall` | Uninstalls `bfs` | - -### Flag-like targets - -The build system provides a few shorthand targets for handy configurations: - -| Command | Description | -|----------------|-------------------------------------------------------------| -| `make release` | Build `bfs` with optimizations, LTO, and without assertions | -| `make asan` | Enable [AddressSanitizer] | -| `make lsan` | Enable [LeakSanitizer] | -| `make msan` | Enable [MemorySanitizer] | -| `make tsan` | Enable [ThreadSanitizer] | -| `make ubsan` | Enable [UndefinedBehaviorSanitizer] | -| `make gcov` | Enable [code coverage] | - -[AddressSanitizer]: https://github.com/google/sanitizers/wiki/AddressSanitizer -[LeakSanitizer]: https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#stand-alone-mode -[MemorySanitizer]: https://github.com/google/sanitizers/wiki/MemorySanitizer -[ThreadSanitizer]: https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual -[UndefinedBehaviorSanitizer]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html -[code coverage]: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html - -You can combine multiple flags and other targets (e.g. `make asan ubsan check`), but not all of them will work together. - -### Flags - -Other flags are controlled with `make` variables and/or environment variables. -Here are some of the common ones; check the [`Makefile`](/Makefile) for more. - -| Flag | Description | -|----------------------------------|---------------------------------------------| -| `CC` | The C compiler to use, e.g. `make CC=clang` | -| `CFLAGS`
`EXTRA_CFLAGS` | Override/add to the default compiler flags | -| `LDFLAGS`
`EXTRA_LDFLAGS` | Override/add to the linker flags | -| `WITH_ACL`
`WITH_ATTR`
... | Enable/disable optional dependencies | -| `TEST_FLAGS` | `tests.sh` flags for `make check` | -| `DESTDIR` | The root directory for `make install` | -| `PREFIX` | The installation prefix (default: `/usr`) | -| `MANDIR` | The man page installation directory | - -### Dependency tracking - -The build system automatically tracks header dependencies with the `-M` family of compiler options (see `DEPFLAGS` in the `Makefile`). -So if you edit a header file, `make` will rebuild the necessary object files ensuring they don't go out of sync. - -We go one step further than most build systems by tracking the flags that were used for the previous compilation. -That means you can change configurations without having to `make clean`. -For example, - - $ make - $ make release - -will build the project in debug mode and then rebuild it in release mode. - -A side effect of this may be surprising: `make check` by itself will rebuild the project in the default configuration. -To test a different configuration, you'll have to repeat it (e.g. `make release check`). - - -Testing -------- - -`bfs` comes with an extensive testsuite which can be run with - - $ make check - -Most of the testsuite is implemented in the file [`tests.sh`](/tests.sh). -This script contains hundreds of separate test cases. -Most of them are *snapshot tests* which compare `bfs`'s output to a known-good copy saved under [`tests`](/tests). - -You can pass the name of a particular test case (or a few) to run just those tests. -For example: - - $ ./tests.sh test_basic - -If you need to update the reference snapshot, pass `--update`. -It can be handy to generate the snapshot with a different `find` implementation to ensure the output is correct, for example: - - $ ./tests.sh test_basic --bfs=find --update - -But keep in mind, other `find` implementations may not be correct. -To my knowledge, no other implementation passes even the POSIX-compatible subset of the tests: - - $ ./tests.sh --bfs=find --posix - ... - tests passed: 89 - tests failed: 5 - -Run - - $ ./tests.sh --help - -for more details. - -### Validation - -A more thorough testsuite is run by the [CI](https://github.com/tavianator/bfs/actions) and to validate releases. -It builds `bfs` in multiple configurations to test for latent bugs, memory leaks, 32-bit compatibility, etc. -You can run it yourself with - - $ make distcheck - -Some of these tests require `sudo`, and will prompt for your password if necessary. - - -Hacking -------- - -`bfs` is written in [C](https://en.wikipedia.org/wiki/C_(programming_language)), specifically [C11](https://en.wikipedia.org/wiki/C11_(C_standard_revision)). -You can get a feel for the coding style by skimming the source code. -[`main.c`](src/main.c) contains an overview of the rest of source files. -A quick summary: - -- Tabs for indentation, spaces for alignment. -- Most types and functions should be namespaced with `bfs_`. - Exceptions are made for things that could be generally useful outside of `bfs`. -- Error handling follows the C standard library conventions: return a nonzero `int` or a `NULL` pointer, with the error code in `errno`. - All failure cases should be handled, including `malloc()` failures. -- `goto` is not harmful for cleaning up in error paths. - -### Adding tests - -Both new features and bug fixes should have associated tests. -To add a test, create a new function in `tests.sh` called `test_`. -Snapshot tests use the `bfs_diff` function to automatically compare the generated and expected outputs. -For example, - -```bash -function test_something() { - bfs_diff basic -name something -} -``` - -`basic` is one of the directory trees generated for test cases; others include `links`, `loops`, `deep`, and `rainbow`. - -Run `./tests.sh test_something --update` to generate the reference snapshot (and don't forget to `git add` it). -Finally, add the test case to one of the arrays `posix_tests`, `bsd_tests`, `gnu_tests`, or `bfs_tests` depending on which `find` implementations it should be compatible with. diff --git a/Makefile b/Makefile index 459a406..c10814a 100644 --- a/Makefile +++ b/Makefile @@ -280,7 +280,7 @@ install: $(MKDIR) $(DESTDIR)$(PREFIX)/bin $(INSTALL) -m755 bfs $(DESTDIR)$(PREFIX)/bin/bfs $(MKDIR) $(DESTDIR)$(MANDIR)/man1 - $(INSTALL) -m644 bfs.1 $(DESTDIR)$(MANDIR)/man1/bfs.1 + $(INSTALL) -m644 docs/bfs.1 $(DESTDIR)$(MANDIR)/man1/bfs.1 $(MKDIR) $(DESTDIR)$(PREFIX)/share/bash-completion/completions $(INSTALL) -m644 completions/bfs.bash $(DESTDIR)$(PREFIX)/share/bash-completion/completions/bfs $(MKDIR) $(DESTDIR)$(PREFIX)/share/zsh/site-functions diff --git a/RELEASES.md b/RELEASES.md deleted file mode 100644 index aafc497..0000000 --- a/RELEASES.md +++ /dev/null @@ -1,655 +0,0 @@ -2.* -=== - -2.5 ---- - -**March 27, 2022** - -- Added compiler-style context for errors and warnings. - Errors look like this: - - $ bfs -nam needle - bfs: error: bfs -nam needle - bfs: error: ~~~~ - bfs: error: Unknown argument; did you mean -name? - - and warnings look like this: - - $ bfs -print -name 'needle' - bfs: warning: bfs -print -name needle - bfs: warning: ~~~~~~~~~~~~ - bfs: warning: The result of this expression is ignored. - -- Updated from C99 to C11 - -- Fixed the tests when built against musl - -- Fixed a build error reported on Manjaro - - -2.4.1 ------ - -**February 24, 2022** - -- Fixed the build when Oniguruma is not installed in the default search paths ([#82]) - -- Fixed string encoding bugs with Oniguruma enabled - -- Fixed regex error reporting bugs - -[#82]: https://github.com/tavianator/bfs/issues/82 - - -2.4 ---- - -**February 22, 2022** - -- Added the Oniguruma regular expression library as an (optional, but enabled by default) dependency ([#81]). - Oniguruma supports more regular expression syntax types than the POSIX regex API, and often performs better. - To build `bfs` without this new dependency, do `make WITH_ONIGURUMA=` to disable it. - Thanks @data-man! - -- Added support for the `ed`, `emacs`, `grep`, and `sed` regular expression types ([#21]) - -- Before executing a process with `-exec[dir]`/`-ok[dir]`, `bfs` now ensures all output streams are flushed. - Previously, I/O from subprocesses could be interleaved unpredictably with buffered I/O from `bfs` itself. - -[#81]: https://github.com/tavianator/bfs/pull/81 -[#21]: https://github.com/tavianator/bfs/issues/21 - - -2.3.1 ------ - -**January 21, 2022** - -- Fixed the build on Debian kFreeBSD - -- Fixed a crash on GNU Hurd when piping bfs's output - -- Fixed a double-`close()` on non-Linux platforms if `fdopendir()` fails - -- Reduced memory allocations on startup - - -2.3 ---- - -**November 25, 2021** - -- More tweaks to `PAGER` and `LESS` handling for `bfs -help` ([#76]) - -- Use 512-byte blocks for `-ls` when `POSIXLY_CORRECT` is set ([#77]) - -- Implemented `-files0-from FILE` to take a list of `'\0'`-separated starting paths. - GNU find will implement the same feature in an upcoming release. - -- Added colors to `-printf` output ([#62]) - -- Faster recovery from `E2BIG` during `-exec` - -[#76]: https://github.com/tavianator/bfs/issues/76 -[#77]: https://github.com/tavianator/bfs/issues/77 -[#62]: https://github.com/tavianator/bfs/issues/62 - - -2.2.1 ------ - -**June 2, 2021** - -- Fixed some incorrect coloring of broken links when links are being followed (`-L`) - -- Made the tests work when run as root by dropping privileges. - This may be helpful for certain packaging or CI environments, but is not recommended. - -- Treat empty `PAGER` and `LESS` environment variables like they're unset, for `bfs -help` ([#71]). - Thanks @markus-oberhumer! - -- The soft `RLIMIT_NOFILE` is now raised automatically to a fairly large value when possible. - This provides a minor performance benefit for large directory trees. - -- Implemented time units for `-mtime` as found in FreeBSD find ([#75]) - -[#71]: https://github.com/tavianator/bfs/issues/71 -[#75]: https://github.com/tavianator/bfs/issues/75 - - -2.2 ---- - -**March 6, 2021** - -- Fixed `-hidden` on hidden start paths - -- Added a Bash completion script. - Thanks @bmundt6! - -- Fixed rounding in `-used`. - Corresponding fixes were made to GNU find in version 4.8.0. - -- Optimized the open directory representation. - On Linux, much libc overhead is bypassed by issuing syscalls directly. - On all platforms, a few fewer syscalls and open file descriptors will be used. - -- Implemented `-flags` from BSD find - - -2.1 ---- - -**November 11, 2020** - -- Added a new `-status` option that displays the search progress in a bar at the bottom of the terminal - -- Fixed an optimizer bug introduced in version 2.0 that affected some combinations of `-user`/`-group` and `-nouser`/`-nogroup` - - -2.0 ---- - -**October 14, 2020** - -- [#8]: New `-exclude ` syntax to more easily and reliably filter out paths. - For example: - - bfs -name config -exclude -name .git - - will find all files named `config`, without searching any directories (or files) named `.git`. - In this case, the same effect could have been achieved (more awkwardly) with `-prune`: - - bfs ! \( -name .git -prune \) -name config - - But `-exclude` will work in more cases: - - # -exclude works with -depth, while -prune doesn't: - bfs -depth -name config -exclude -name .git - - # -exclude applies even to paths below the minimum depth: - bfs -mindepth 3 -name config -exclude -name .git - -- [#30]: `-nohidden` is now equivalent to `-exclude -hidden`. - This changes the behavior of command lines like - - bfs -type f -nohidden - - to do what was intended. - -- Optimized the iterative deepening (`-S ids`) implementation - -- Added a new search strategy: exponential deepening search (`-S eds`). - This strategy provides many of the benefits of iterative deepening, but much faster due to fewer re-traversals. - -- Fixed an optimizer bug that could skip `-empty`/`-xtype` if they didn't always lead to an action - -- Implemented `-xattrname` to find files with a particular extended attribute (from macOS find) - -- Made `-printf %l` still respect the width specifier (e.g. `%10l`) for non-links, to match GNU find - -- Made `bfs` fail if `-color` is given explicitly and `LS_COLORS` can't be parsed, rather than falling back to non-colored output - -[#8]: https://github.com/tavianator/bfs/issues/8 -[#30]: https://github.com/tavianator/bfs/issues/30 - - -1.* -=== - -1.7 ---- - -**April 22, 2020** - -- Fixed `-ls` printing numeric IDs instead of user/group names in large directory trees -- Cached the user and group tables for a performance boost -- Fixed interpretation of "default" ACLs -- Implemented `-s` flag to sort results - - -1.6 ---- - -**February 25, 2020** - -- Implemented `-newerXt` (explicit reference times), `-since`, `-asince`, etc. -- Fixed `-empty` to skip special files (pipes, devices, sockets, etc.) - - -1.5.2 ------ - -**January 9, 2020** - -- Fixed the build on NetBSD -- Added support for NFSv4 ACLs on FreeBSD -- Added a `+` after the file mode for files with ACLs in `-ls` -- Supported more file types (whiteouts, doors) in symbolic modes for `-ls`/`-printf %M` -- Implemented `-xattr` on FreeBSD - - -1.5.1 ------ - -**September 14, 2019** - -- Added a warning to `-mount`, since it will change behaviour in the next POSIX revision -- Added a workaround for environments that block `statx()` with `seccomp()`, like older Docker -- Fixed coloring of nonexistent leading directories -- Avoided calling `stat()` on all mount points at startup - - -1.5 ---- - -**June 27, 2019** - -- New `-xattr` predicate to find files with extended attributes -- Fixed the `-acl` implementation on macOS -- Implemented depth-first (`-S dfs`) and iterative deepening search (`-S ids`) -- Piped `-help` output into `$PAGER` by default -- Fixed crashes on some invalid `LS_COLORS` values - - -1.4.1 ------ - -**April 5, 2019** - -- Added a nicer error message when the tests are run as root -- Fixed detection of comparison expressions with signs, to match GNU find for things like `-uid ++10` -- Added support for https://no-color.org/ -- Decreased the number of `stat()` calls necessary in some cases - - -1.4 ---- - -**April 15, 2019** - -- New `-unique` option that filters out duplicate files ([#48]) -- Optimized the file coloring implementation -- Fixed the coloring implementation to match GNU ls more closely in many corner cases - - Implemented escape sequence parsing for `LS_COLORS` - - Implemented `ln=target` for coloring links like their targets - - Fixed the order of fallbacks used when some color keys are unset -- Add a workaround for incorrect file types for bind-mounted files on Linux ([#37]) - -[#48]: https://github.com/tavianator/bfs/issues/48 -[#37]: https://github.com/tavianator/bfs/issues/37 - - -1.3.3 ------ - -**February 10, 2019** - -- Fixed unpredictable behaviour for empty responses to `-ok`/`-okdir` caused by an uninitialized string -- Writing to standard output now causes `bfs` to fail if the descriptor was closed -- Fixed incomplete file coloring in error messages -- Added some data flow optimizations -- Fixed `-nogroup`/`-nouser` in big directory trees -- Added `-type w` for whiteouts, as supported by FreeBSD `find` -- Re-wrote the `-help` message and manual page - - -1.3.2 ------ - -**January 11, 2019** - -- Fixed an out-of-bounds read if LS_COLORS doesn't end with a `:` -- Allowed multiple debug flags to be specified like `-D opt,tree` - - -1.3.1 ------ - -**January 3, 2019** - -- Fixed some portability problems affecting FreeBSD - - -1.3 ---- - -**January 2, 2019** - -New features: - -- `-acl` finds files with non-trivial Access Control Lists (from FreeBSD) -- `-capable` finds files with capabilities set -- `-D all` turns on all debugging flags at once - -Fixes: - -- `LS_COLORS` handling has been improved: - - Extension colors are now case-insensitive like GNU `ls` - - `or` (orphan) and `mi` (missing) files are now treated differently - - Default colors can be unset with `di=00` or similar - - Specific colors fall back to more general colors when unspecified in more places - - `LS_COLORS` no longer needs a trailing colon -- `-ls`/`-fls` now prints the major/minor numbers for device nodes -- `-exec ;` is rejected rather than segfaulting -- `bfs` now builds on old Linux versions that require `-lrt` for POSIX timers -- For files whose access/change/modification times can't be read, `bfs` no longer fails unless those times are needed for tests -- The testsuite is now more correct and portable - - -1.2.4 ------ - -**September 24, 2018** - -- GNU find compatibility fixes for `-printf`: - - `%Y` now prints `?` if an error occurs resolving the link - - `%B` is now supported for birth/creation time (as well as `%W`/`%w`) - - All standard `strftime()` formats are supported, not just the ones from the GNU find manual -- Optimizations are now re-run if any expressions are reordered -- `-exec` and friends no longer leave zombie processes around when `exec()` fails - - -1.2.3 ------ - -**July 15, 2018** - -- Fixed `test_depth_error` on filesystems that don't fill in `d_type` -- Fixed the build on Linux architectures that don't have the `statx()` syscall (ia64, sh4) -- Fixed use of AT_EMPTY_PATH for fstatat on systems that don't support it (Hurd) -- Fixed `ARG_MAX` accounting on architectures with large pages (ppc64le) -- Fixed the build against the upcoming glibc 2.28 release that includes its own `statx()` wrapper - - -1.2.2 ------ - -**June 23, 2018** - -- Minor bug fixes: - - Fixed `-exec ... '{}' +` argument size tracking after recovering from `E2BIG` - - Fixed `-fstype` if `/proc` is available but `/etc/mtab` is not - - Fixed an uninitialized variable when given `-perm +rw...` - - Fixed some potential "error: 'path': Success" messages -- Reduced reliance on GNU coreutils in the testsuite -- Refactored and simplified the internals of `bftw()` - - -1.2.1 ------ - -**February 8, 2018** - -- Performance optimizations - - -1.2 ---- - -**January 20, 2018** - -- Added support for the `-perm +7777` syntax deprecated by GNU find (equivalent to `-perm /7777`), for compatibility with BSD finds -- Added support for file birth/creation times on platforms that report it - - `-Bmin`/`-Btime`/`-Bnewer` - - `B` flag for `-newerXY` - - `%w` and `%Wk` directives for `-printf` - - Uses the `statx(2)` system call on new enough Linux kernels -- More robustness to `E2BIG` added to the `-exec` implementation - - -1.1.4 ------ - -**October 27, 2017** - -- Added a man page -- Fixed cases where multiple actions write to the same file -- Report errors that occur when closing files/flushing streams -- Fixed "argument list too long" errors with `-exec ... '{}' +` - - -1.1.3 ------ - -**October 4, 2017** - -- Refactored the optimizer -- Implemented data flow optimizations - - -1.1.2 ------ - -**September 10, 2017** - -- Fixed `-samefile` and similar predicates when passed broken symbolic links -- Implemented `-fstype` on Solaris -- Fixed `-fstype` under musl -- Implemented `-D search` -- Implemented a cost-based optimizer - - -1.1.1 ------ - -**August 10, 2017** - -- Re-licensed under the BSD Zero Clause License -- Fixed some corner cases with `-exec` and `-ok` parsing - - -1.1 ---- - -**July 22, 2017** - -- Implemented some primaries from NetBSD `find`: - - `-exit [STATUS]` (like `-quit`, but with an optional explicit exit status) - - `-printx` (escape special characters for `xargs`) - - `-rm` (alias for `-delete`) -- Warn if `-prune` will have no effect due to `-depth` -- Handle y/n prompts according to the user's locale -- Prompt the user to correct typos without having to re-run `bfs` -- Fixed handling of paths longer than `PATH_MAX` -- Fixed spurious "Inappropriate ioctl for device" errors when redirecting `-exec ... +` output -- Fixed the handling of paths that treat a file as a directory (e.g. `a/b/c` where `a/b` is a regular file) -- Fixed an expression optimizer bug that broke command lines like `bfs -name '*' -o -print` - - -1.0.2 ------ - -**June 15, 2017** - -Bugfix release. - -- Fixed handling of \0 inside -printf format strings -- Fixed `-perm` interpretation of permcopy actions (e.g. `u=rw,g=r`) - - -1.0.1 ------ - -**May 17, 2017** - -Bugfix release. - -- Portability fixes that mostly affect GNU Hurd -- Implemented `-D exec` -- Made `-quit` not disable the implicit `-print` - - -1.0 ---- - -**April 24, 2017** - -This is the first release of bfs with support for all of GNU find's primitives. - -Changes since 0.96: - -- Implemented `-fstype` -- Implemented `-exec/-execdir ... +` -- Implemented BSD's `-X` -- Fixed the tests under Bash 3 (mostly for macOS) -- Some minor optimizations and fixes - - -0.* -=== - - -0.96 ----- - -**March 11, 2017** - -73/76 GNU find features supported. - -- Implemented -nouser and -nogroup -- Implemented -printf and -fprintf -- Implemented -ls and -fls -- Implemented -type with multiple types at once (e.g. -type f,d,l) -- Fixed 32-bit builds -- Fixed -lname on "symlinks" in Linux /proc -- Fixed -quit to take effect as soon as it's reached -- Stopped redirecting standard input from /dev/null for -ok and -okdir, as that violates POSIX -- Many test suite improvements - - -0.88 ----- - -**December 20, 2016** - -67/76 GNU find features supported. - -- Fixed the build on macOS, and some other UNIXes -- Implemented `-regex`, `-iregex`, `-regextype`, and BSD's `-E` -- Implemented `-x` (same as `-mount`/`-xdev`) from BSD -- Implemented `-mnewer` (same as `-newer`) from BSD -- Implemented `-depth N` from BSD -- Implemented `-sparse` from FreeBSD -- Implemented the `T` and `P` suffices for `-size`, for BSD compatibility -- Added support for `-gid NAME` and `-uid NAME` as in BSD - - -0.84.1 ------- - -**November 24, 2016** - -Bugfix release. - -- Fixed [#7] again -- Like GNU find, don't print warnings by default if standard input is not a terminal -- Redirect standard input from /dev/null for -ok and -okdir -- Skip . when -delete'ing -- Fixed -execdir when the root path has no slashes -- Fixed -execdir in / -- Support -perm +MODE for symbolic modes -- Fixed the build on FreeBSD - -[#7]: https://github.com/tavianator/bfs/issues/7 - - -0.84 ----- - -**October 29, 2016** - -64/76 GNU find features supported. - -- Spelling suggestion improvements -- Handle `--` -- (Untested) support for exotic file types like doors, ports, and whiteouts -- Improved robustness in the face of closed std{in,out,err} -- Fixed the build on macOS -- Implement `-ignore_readdir_race`, `-noignore_readdir_race` -- Implement `-perm` - - -0.82 ----- - -**September 4, 2016** - -62/76 GNU find features supported. - -- Rework optimization levels - - `-O1` - - Simple boolean simplification - - `-O2` - - Purity-based optimizations, allowing side-effect-free tests like `-name` or `-type` to be moved or removed - - `-O3` (**default**): - - Re-order tests to reduce the expected cost (TODO) - - `-O4` - - Aggressive optimizations that may have surprising effects on warning/error messages and runtime, but should not otherwise affect the results - - `-Ofast`: - - Always the highest level, currently the same as `-O4` -- Color files with multiple hard links correctly -- Treat `-`, `)`, and `,` as paths when required to by POSIX - - `)` and `,` are only supported before the expression begins -- Implement `-D opt` -- Implement `-D rates` -- Implement `-fprint` -- Implement `-fprint0` -- Implement BSD's `-f` -- Suggest fixes for typo'd arguments - -0.79 ----- - -**May 27, 2016** - -60/76 GNU find features supported. - -- Remove an errant debug `printf()` from `-used` -- Implement the `{} ;` variants of `-exec`, `-execdir`, `-ok`, and `-okdir` - - -0.74 ----- - -**March 12, 2016** - -56/76 GNU find features supported. - -- Color broken symlinks correctly -- Fix [#7] -- Fix `-daystart`'s rounding of midnight -- Implement (most of) `-newerXY` -- Implement `-used` -- Implement `-size` - -[#7]: https://github.com/tavianator/bfs/issues/7 - - -0.70 ----- - -**February 23, 2016** - -53/76 GNU find features supported. - -- New `make install` and `make uninstall` targets -- Squelch non-positional warnings for `-follow` -- Reduce memory footprint by as much as 64% by closing `DIR*`s earlier -- Speed up `bfs` by ~5% by using a better FD cache eviction policy -- Fix infinite recursion when evaluating `! expr` -- Optimize unused pure expressions (e.g. `-empty -a -false`) -- Optimize double-negation (e.g. `! ! -name foo`) -- Implement `-D stat` and `-D tree` -- Implement `-O` - - -0.67 ----- - -**February 14, 2016** - -Initial release. - -51/76 GNU find features supported. diff --git a/bfs.1 b/bfs.1 deleted file mode 100644 index 53a9831..0000000 --- a/bfs.1 +++ /dev/null @@ -1,811 +0,0 @@ -.TH BFS 1 -.SH NAME -bfs \- breadth-first search for your files -.SH SYNOPSIS -.B bfs -.RB [ flags ...] -.RI [ paths ...] -.RB [ expression ...] -.PP -flags -.RB ( \-H / \-L / \-P -etc.), -.IR paths , -and -.B expressions -may be freely mixed in any order. -.SH DESCRIPTION -.B bfs -is a breadth-first version of the UNIX -.BR find (1) -command. -.PP -.B bfs -supports almost every feature from every major -.BR find (1) -implementation, so your existing command lines should work as-is. -It also adds some features of its own, such as a more forgiving command line parser and some additional options. -.PP -Each -.I path -specified on the command line is treated as a starting path to search through. -If no paths are specified, the current directory -.RI ( . ) -is searched by default. -.PP -Like -.BR find (1), -.B bfs -interprets its arguments as a short-circuiting Boolean expression. -For example, -.PP -.nf -.RS -.B bfs \\\( \-name '*.txt' \-or \-lname '*.txt' \\\\) \-and \-print -.RE -.fi -.PP -will print the all the paths that are either .txt files or symbolic links to .txt files. -.B \-and -is implied between two consecutive expressions, so this is equivalent: -.PP -.nf -.RS -.B bfs \\\( \-name '*.txt' \-or \-lname '*.txt' \\\\) \-print -.RE -.fi -.PP -Finally, -.B \-print -is implied if no actions are specified, so this too is equivalent: -.PP -.nf -.RS -.B bfs \-name '*.txt' \-or \-lname '*.txt' -.RE -.fi -.PP -Most options that take a numeric argument -.I N -will also accept -.I \-N -or -.IR +N . -.IR \-N -means "less than -.IR N ," -and -.I +N -means "greater than -.IR N ." -.SH FLAGS -.TP -.B \-H -Follow symbolic links on the command line, but not while searching. -.TP -.B \-L -Follow all symbolic links. -.TP -.B \-P -Never follow symbolic links (the default). -.TP -.B \-E -Use extended regular expressions (same as \fB\-regextype posix-extended\fR). -.TP -.B \-X -Filter out files with -.RB non- xargs (1)-safe -names. -.TP -.B \-d -Search in post-order (same as -.BR \-depth ). -.TP -.B \-s -Visit directory entries in sorted order. -The sorting takes place within each directory separately, which makes it different from -.B bfs ... | -.BR sort , -but still provides a deterministic ordering. -.TP -.B \-x -Don't descend into other mount points (same as \fB\-xdev\fR). -.TP -\fB\-f \fIPATH\fR -Treat -.I PATH -as a path to search (useful if it begins with a dash). -.PP -.TP -\fB\-D \fIFLAG\fR -Turn on a debugging flag (see -.B \-D -.IR help ). -.PP -\fB\-O\fIN\fR -.RS -Enable optimization level -.I N -(default: -.IR 3 ). -.TP -.BI \-O 0 -Disable all optimizations. -.TP -.BI \-O 1 -Basic logical simplifications. -.TP -.BI \-O 2 -All -.BI \-O 1 -optimizations, plus dead code elimination and data flow analysis. -.TP -.BI \-O 3 -All -.BI \-O 2 -optimizations, plus re-order expressions to reduce expected cost. -.TP -\fB\-O\fI4\fR/\fB\-O\fIfast\fR -All optimizations, including aggressive optimizations that may alter the observed behavior in corner cases. -.RE -.PP -\fB\-S \fIbfs\fR|\fIdfs\fR|\fIids\fR|\fIeds\fR -.RS -Choose the search strategy. -.TP -.I bfs -Breadth-first search (the default). -.TP -.I dfs -Depth-first search. -Uses less memory than breadth-first search, but is typically slower to return relevant results. -.TP -.I ids -Iterative deepening search. -Performs repeated depth-first searches with increasing depth limits. -This gives results in the same order as breadth-first search, but with the reduced memory consumption of depth-first search. -Tends to be very slow in practice, so use it only if you absolutely need breadth-first ordering, but -.B \-S -.I bfs -consumes too much memory. -.TP -.I eds -Exponential deepening search. -A compromise between breadth- and depth-first search, which searches exponentially increasing depth ranges (e.g 0-1, 1-2, 2-4, 4-8, etc.). -Provides many of the benefits of breadth-first search with depth-first's reduced memory consumption. -Typically far faster than -.B \-S -.IR ids . -.RE -.SH OPERATORS -.TP -\fB( \fIexpression \fB)\fR -Parentheses are used for grouping expressions together. -You'll probably have to write -.B \\\\( -.I expression -.B \\\\) -to avoid the parentheses being interpreted by the shell. -.PP -\fB! \fIexpression\fR -.br -\fB\-not \fIexpression\fR -.RS -The "not" operator: returns the negation of the truth value of the -.IR expression . -You may have to write \fB\\! \fIexpression\fR to avoid \fB!\fR being interpreted by the shell. -.RE -.PP -\fIexpression\fR \fIexpression\fR -.br -\fIexpression \fB\-a \fIexpression\fR -.br -\fIexpression \fB\-and \fIexpression\fR -.RS -Short-circuiting "and" operator: if the left-hand -.I expression -is -.BR true , -returns the right-hand -.IR expression ; -otherwise, returns -.BR false . -.RE -.PP -\fIexpression \fB\-o \fIexpression\fR -.br -\fIexpression \fB\-or \fIexpression\fR -.RS -Short-circuiting "or" operator: if the left-hand -.I expression -is -.BR false , -returns the right-hand -.IR expression ; -otherwise, returns -.BR true . -.RE -.TP -\fIexpression \fB, \fIexpression\fR -The "comma" operator: evaluates the left-hand -.I expression -but discards the result, returning the right-hand -.IR expression . -.SH SPECIAL FORMS -.TP -\fB\-exclude \fIexpression\fR -Exclude all paths matching the -.I expression -from the search. -This is more powerful than -.BR \-prune , -because it applies even when the expression wouldn't otherwise be evaluated, due to -.B \-depth -or -.B \-mindepth -for example. -Exclusions are always applied before other expressions, so it may be least confusing to put them first on the command line. -.SH OPTIONS -.PP -.B \-color -.br -.B \-nocolor -.RS -Turn colors on or off (default: -.B \-color -if outputting to a terminal, -.B \-nocolor -otherwise). -.RE -.TP -.B \-daystart -Measure time relative to the start of today. -.TP -.B \-depth -Search in post-order (descendents first). -.TP -.B \-follow -Follow all symbolic links (same as -.BR \-L ). -.TP -\fB\-files0\-from \fIFILE\fR -Treat the NUL ('\\0')-separated paths in -.I FILE -as starting points for the search. -Pass -.B \-files0\-from -.I \- -to read the paths from standard input. -.PP -\fB\-ignore_readdir_race\fR -.br -\fB\-noignore_readdir_race\fR -.RS -Whether to report an error if -.B bfs -detects that the file tree is modified during the search (default: -.BR \-noignore_readdir_race ). -.RE -.PP -\fB\-maxdepth \fIN\fR -.br -\fB\-mindepth \fIN\fR -.RS -Ignore files deeper/shallower than -.IR N . -.RE -.TP -.B \-mount -Don't descend into other mount points (same as -.B \-xdev -for now, but will skip mount points entirely in the future). -.TP -.B \-nohidden -Exclude hidden files and directories. -.TP -.B \-noleaf -Ignored; for compatibility with GNU find. -.TP -\fB\-regextype \fITYPE\fR -Use -.IR TYPE -flavored -regexes (default: -.IR posix-basic ; -see -.B \-regextype -.IR help ). -.TP -.B \-status -Display a status bar while searching. -.TP -.B \-unique -Skip any files that have already been seen. -Particularly useful along with -.BR \-L . -.PP -.B \-warn -.br -.B \-nowarn -.RS -Turn on or off warnings about the command line. -.RE -.TP -.B \-xdev -Don't descend into other mount points. -.SH TESTS -.TP -.B \-acl -Find files with a non-trivial Access Control List -.RB ( acl (5)). -.PP -\fB\-amin\fR [\fI\-+\fR]\fIN\fR -.br -\fB\-Bmin\fR [\fI\-+\fR]\fIN\fR -.br -\fB\-cmin\fR [\fI\-+\fR]\fIN\fR -.br -\fB\-mmin\fR [\fI\-+\fR]\fIN\fR -.RS -Find files -.BR a ccessed/ B irthed/ c hanged/ m odified -.I N -minutes ago. -.RE -.PP -\fB\-anewer \fIFILE\fR -.br -\fB\-Bnewer \fIFILE\fR -.br -\fB\-cnewer \fIFILE\fR -.br -\fB\-mnewer \fIFILE\fR -.RS -Find files -.BR a ccessed/ B irthed/ c hanged/ m odified -more recently than -.I FILE -was modified. -.RE -.PP -\fB\-asince \fITIME\fR -.br -\fB\-Bsince \fITIME\fR -.br -\fB\-csince \fITIME\fR -.br -\fB\-msince \fITIME\fR -.RS -Find files -.BR a ccessed/ B irthed/ c hanged/ m odified -more recently than the ISO 8601-style timestamp -.IR TIME . -See -.BI \-newer XY -for examples of the timestamp format. -.RE -.PP -\fB\-atime\fR [\fI\-+\fR]\fIN\fR -.br -\fB\-Btime\fR [\fI\-+\fR]\fIN\fR -.br -\fB\-ctime\fR [\fI\-+\fR]\fIN\fR -.br -\fB\-mtime\fR [\fI\-+\fR]\fIN\fR -.RS -Find files -.BR a ccessed/ B irthed/ c hanged/ m odified -.I N -days ago. -.RE -.TP -.B \-capable -Find files with POSIX.1e -.BR capabilities (7) -set. -.TP -\fB\-depth\fR [\fI\-+\fR]\fIN\fR -Find files with depth -.IR N . -.TP -.B \-empty -Find empty files/directories. -.PP -.B \-executable -.br -.B \-readable -.br -.B \-writable -.RS -Find files the current user can execute/read/write. -.RE -.PP -.B \-false -.br -.B \-true -.RS -Always false/true. -.RE -.TP -.B \-fstype TYPE -Find files on file systems with the given -.BR TYPE . -.PP -\fB\-gid\fR [\fI\-+\fR]\fIN\fR -.br -\fB\-uid\fR [\fI\-+\fR]\fIN\fR -.RS -Find files owned by group/user ID -.IR N . -.RE -.PP -\fB\-group \fINAME\fR -.br -\fB\-user \fINAME\fR -.RS -Find files owned by the group/user -.IR NAME . -.RE -.TP -.B \-hidden -Find hidden files (those beginning with -.IR . ). -.PP -\fB\-ilname \fIGLOB\fR -.br -\fB\-iname \fIGLOB\fR -.br -\fB\-ipath \fIGLOB\fR -.br -\fB\-iregex \fIREGEX\fR -.br -\fB\-iwholename \fIGLOB\fR -.RS -Case-insensitive versions of -.BR \-lname / \-name / \-path / \-regex / \-wholename . -.RE -.TP -\fB\-inum\fR [\fI\-+\fR]\fIN\fR -Find files with inode number -.IR N . -.TP -\fB\-links\fR [\fI\-+\fR]\fIN\fR -Find files with -.I N -hard links. -.TP -\fB\-lname \fIGLOB\fR -Find symbolic links whose target matches the -.IR GLOB . -.TP -\fB\-name \fIGLOB\fR -Find files whose name matches the -.IR GLOB . -.TP -\fB\-newer \fIFILE\fR -Find files newer than -.IR FILE . -.TP -\fB\-newer\fIXY \fIREFERENCE\fR -Find files whose -.I X -time is newer than the -.I Y -time of -.IR REFERENCE . -.I X -and -.I Y -can be any of -.RI [ aBcm ] -.RI ( a ccess/ B irth/ c hange/ m odification). -.I Y -may also be -.I t -to parse -.I REFERENCE -as an ISO 8601-style timestamp. For example: -.PP -.RS -1991-12-14 -.br -1991-12-14T03:00 -.br -1991-12-14T03:00-07:00 -.br -1991-12-14T10:00Z -.RE -.PP -.B \-nogroup -.br -.B \-nouser -.RS -Find files owned by nonexistent groups/users. -.RE -.PP -\fB\-path \fIGLOB\fR -.br -\fB\-wholename \fIGLOB\fR -.RS -Find files whose entire path matches the -.IR GLOB . -.RE -.TP -\fB\-perm\fR [\fI\-\fR]\fIMODE\fR -Find files with a matching mode. -.TP -\fB\-regex \fIREGEX\fR -Find files whose entire path matches the regular expression -.IR REGEX . -.TP -\fB\-samefile \fIFILE\fR -Find hard links to -.IR FILE . -.TP -\fB\-since \fITIME\fR -Find files modified since the ISO 8601-style timestamp -.IR TIME . -See -.BI \-newer XY -for examples of the timestamp format. -.TP -\fB\-size\fR [\fI\-+\fR]\fIN\fR[\fIcwbkMGTP\fR] -Find files with the given size, in 1-byte -.IR c haracters, -2-byte -.IR w ords, -512-byte -.IR b locks -(default), or -.IR k iB/ M iB/ G iB/ T iB/ P iB. -.TP -.B \-sparse -Find files that occupy fewer disk blocks than expected. -.TP -\fB\-type\fR [\fIbcdlpfswD\fR] -Find files of the given type. -Possible types are -.IR b lock -device, -.IR c haracter -device, -.IR d irectory, -symbolic -.IR l ink, -.IR p ipe, -regular -.IR f ile, -.IR s ocket, -.IR w hiteout, -and -.IR D oor. -.TP -\fB\-used\fR [\fI\-+\fR]\fIN\fR -Find files last accessed -.I N -days after they were changed. -.TP -.B \-xattr -Find files with extended attributes -.RB ( xattr (7)). -.TP -\fB\-xattrname\fR \fINAME\fR -Find files with the extended attribute -.IR NAME . -.TP -\fB\-xtype\fR [\fIbcdlpfswD\fR] -Find files of the given type, following links when -.B \-type -would not, and vice versa. -.SH ACTIONS -.PP -.B \-delete -.br -.B \-rm -.RS -Delete any found files (implies \fB-depth\fR). -.RE -.TP -\fB\-exec \fIcommand ... {} ;\fR -Execute a command. -.TP -\fB\-exec \fIcommand ... {} +\fR -Execute a command with multiple files at once. -.TP -\fB\-ok \fIcommand ... {} ;\fR -Prompt the user whether to execute a command. -.PP -\fB\-execdir \fIcommand ... {} ;\fR -.br -\fB\-execdir \fIcommand ... {} +\fR -.br -\fB\-okdir \fIcommand ... {} ;\fR -.RS -Like -.BR \-exec / \-ok , -but run the command in the same directory as the found file(s). -.RE -.TP -\fB\-exit\fR [\fISTATUS\fR] -Exit immediately with the given status (0 if unspecified). -.PP -\fB\-fls \fIFILE\fR -.br -\fB\-fprint \fIFILE\fR -.br -\fB\-fprint0 \fIFILE\fR -.br -\fB\-fprintf \fIFILE FORMAT\fR -.RS -Like -.BR \-ls / \-print / \-print0 / \-printf , -but write to -.I FILE -instead of standard output. -.RE -.TP -.B \-ls -List files like -.B ls -.IR \-dils . -.TP -.B \-print -Print the path to the found file. -.TP -.B \-print0 -Like -.BR \-print , -but use the null character ('\\0') as a separator rather than newlines. -Useful in conjunction with -.B xargs -.IR \-0 . -.TP -\fB\-printf \fIFORMAT\fR -Print according to a format string (see -.BR find (1)). -These additional format directives are supported: -.RS -.TP -%w -The file's birth time, in the same format as %a/%c/%t. -.TP -.RI %W k -Field -.I k -of the file's birth time, in the same format as -.RI %A k /%C k /%T k . -.RE -.TP -.B \-printx -Like -.BR \-print , -but escape whitespace and quotation characters, to make the output safe for -.BR xargs (1). -Consider using -.B \-print0 -and -.B xargs -.I \-0 -instead. -.TP -.B \-prune -Don't descend into this directory. -.TP -.B \-quit -Quit immediately. -.TP -.B \-version -Print version information. -.TP -.B \-help -Print usage information. -.SH ENVIRONMENT -Certain environment variables affect the behavior of -.BR bfs . -.PP -.B LANG -.br -.B LC_* -.RS -Specifies the -.BR locale (7) -in use for various things. -.B bfs -is not (yet) translated to any languages except English, but the locale will still affect the format of printed values. -Yes/no prompts (e.g. from -.BR \-ok ) -will also be interpreted according to the current locale. -.RE -.PP -.B LS_COLORS -.br -.B BFS_COLORS -.RS -Controls the colors used when displaying file paths if -.B \-color -is enabled. -.B bfs -interprets -.B LS_COLORS -the same way GNU -.BR ls (1) -does (see -.BR dir_colors (5)). -.B BFS_COLORS -can be used to customize -.B bfs -without affecting other commands. -.RE -.TP -.B NO_COLOR -Causes -.B bfs -to default to -.B \-nocolor -if it is set (see https://no-color.org/). -.TP -.B PAGER -Specifies the pager used for -.B \-help -output. -Defaults to -.BR more (1). -.TP -.B POSIXLY_CORRECT -Makes -.B bfs -conform more strictly to the POSIX.1-2017 specification for -.BR find (1). -Currently this just disables warnings by default. -It does not disable -.BR bfs 's -various extensions to the base POSIX functionality. -.SH EXAMPLES -.TP -.B bfs -With no arguments, -.B bfs -prints all files under the current directory in breadth-first order. -.TP -.B bfs \-name '*.txt' -Prints all the .txt files under the current directory. -.B *.txt -is quoted to ensure the glob is processed by -.B bfs -rather than the shell. -.TP -\fBbfs \-name access_log \-L \fI/var\fR -Finds all files named -.B access_log -under -.IR /var , -following symbolic links. -.B bfs -allows flags and paths to appear anywhere on the command line. -.TP -\fBbfs \fI~ \fB\-not \-user $USER\fR -Prints all files in your home directory not owned by you. -.TP -.B bfs \-xtype l -Finds broken symbolic links. -.TP -.B bfs \-name config \-exclude \-name .git -Finds all files named -.BR config, -skipping every -.B .git -directory. -.TP -.B bfs \-type f \-executable \-exec strip '{}' + -Runs -.BR strip (1) -on all executable files it finds, passing it multiple files at a time. -.SH BUGS -https://github.com/tavianator/bfs/issues -.SH AUTHOR -Tavian Barnes -.PP -https://tavianator.com/projects/bfs.html -.SH SEE ALSO -.BR find (1), -.BR locate (1), -.BR xargs (1) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 0000000..aafc497 --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1,655 @@ +2.* +=== + +2.5 +--- + +**March 27, 2022** + +- Added compiler-style context for errors and warnings. + Errors look like this: + + $ bfs -nam needle + bfs: error: bfs -nam needle + bfs: error: ~~~~ + bfs: error: Unknown argument; did you mean -name? + + and warnings look like this: + + $ bfs -print -name 'needle' + bfs: warning: bfs -print -name needle + bfs: warning: ~~~~~~~~~~~~ + bfs: warning: The result of this expression is ignored. + +- Updated from C99 to C11 + +- Fixed the tests when built against musl + +- Fixed a build error reported on Manjaro + + +2.4.1 +----- + +**February 24, 2022** + +- Fixed the build when Oniguruma is not installed in the default search paths ([#82]) + +- Fixed string encoding bugs with Oniguruma enabled + +- Fixed regex error reporting bugs + +[#82]: https://github.com/tavianator/bfs/issues/82 + + +2.4 +--- + +**February 22, 2022** + +- Added the Oniguruma regular expression library as an (optional, but enabled by default) dependency ([#81]). + Oniguruma supports more regular expression syntax types than the POSIX regex API, and often performs better. + To build `bfs` without this new dependency, do `make WITH_ONIGURUMA=` to disable it. + Thanks @data-man! + +- Added support for the `ed`, `emacs`, `grep`, and `sed` regular expression types ([#21]) + +- Before executing a process with `-exec[dir]`/`-ok[dir]`, `bfs` now ensures all output streams are flushed. + Previously, I/O from subprocesses could be interleaved unpredictably with buffered I/O from `bfs` itself. + +[#81]: https://github.com/tavianator/bfs/pull/81 +[#21]: https://github.com/tavianator/bfs/issues/21 + + +2.3.1 +----- + +**January 21, 2022** + +- Fixed the build on Debian kFreeBSD + +- Fixed a crash on GNU Hurd when piping bfs's output + +- Fixed a double-`close()` on non-Linux platforms if `fdopendir()` fails + +- Reduced memory allocations on startup + + +2.3 +--- + +**November 25, 2021** + +- More tweaks to `PAGER` and `LESS` handling for `bfs -help` ([#76]) + +- Use 512-byte blocks for `-ls` when `POSIXLY_CORRECT` is set ([#77]) + +- Implemented `-files0-from FILE` to take a list of `'\0'`-separated starting paths. + GNU find will implement the same feature in an upcoming release. + +- Added colors to `-printf` output ([#62]) + +- Faster recovery from `E2BIG` during `-exec` + +[#76]: https://github.com/tavianator/bfs/issues/76 +[#77]: https://github.com/tavianator/bfs/issues/77 +[#62]: https://github.com/tavianator/bfs/issues/62 + + +2.2.1 +----- + +**June 2, 2021** + +- Fixed some incorrect coloring of broken links when links are being followed (`-L`) + +- Made the tests work when run as root by dropping privileges. + This may be helpful for certain packaging or CI environments, but is not recommended. + +- Treat empty `PAGER` and `LESS` environment variables like they're unset, for `bfs -help` ([#71]). + Thanks @markus-oberhumer! + +- The soft `RLIMIT_NOFILE` is now raised automatically to a fairly large value when possible. + This provides a minor performance benefit for large directory trees. + +- Implemented time units for `-mtime` as found in FreeBSD find ([#75]) + +[#71]: https://github.com/tavianator/bfs/issues/71 +[#75]: https://github.com/tavianator/bfs/issues/75 + + +2.2 +--- + +**March 6, 2021** + +- Fixed `-hidden` on hidden start paths + +- Added a Bash completion script. + Thanks @bmundt6! + +- Fixed rounding in `-used`. + Corresponding fixes were made to GNU find in version 4.8.0. + +- Optimized the open directory representation. + On Linux, much libc overhead is bypassed by issuing syscalls directly. + On all platforms, a few fewer syscalls and open file descriptors will be used. + +- Implemented `-flags` from BSD find + + +2.1 +--- + +**November 11, 2020** + +- Added a new `-status` option that displays the search progress in a bar at the bottom of the terminal + +- Fixed an optimizer bug introduced in version 2.0 that affected some combinations of `-user`/`-group` and `-nouser`/`-nogroup` + + +2.0 +--- + +**October 14, 2020** + +- [#8]: New `-exclude ` syntax to more easily and reliably filter out paths. + For example: + + bfs -name config -exclude -name .git + + will find all files named `config`, without searching any directories (or files) named `.git`. + In this case, the same effect could have been achieved (more awkwardly) with `-prune`: + + bfs ! \( -name .git -prune \) -name config + + But `-exclude` will work in more cases: + + # -exclude works with -depth, while -prune doesn't: + bfs -depth -name config -exclude -name .git + + # -exclude applies even to paths below the minimum depth: + bfs -mindepth 3 -name config -exclude -name .git + +- [#30]: `-nohidden` is now equivalent to `-exclude -hidden`. + This changes the behavior of command lines like + + bfs -type f -nohidden + + to do what was intended. + +- Optimized the iterative deepening (`-S ids`) implementation + +- Added a new search strategy: exponential deepening search (`-S eds`). + This strategy provides many of the benefits of iterative deepening, but much faster due to fewer re-traversals. + +- Fixed an optimizer bug that could skip `-empty`/`-xtype` if they didn't always lead to an action + +- Implemented `-xattrname` to find files with a particular extended attribute (from macOS find) + +- Made `-printf %l` still respect the width specifier (e.g. `%10l`) for non-links, to match GNU find + +- Made `bfs` fail if `-color` is given explicitly and `LS_COLORS` can't be parsed, rather than falling back to non-colored output + +[#8]: https://github.com/tavianator/bfs/issues/8 +[#30]: https://github.com/tavianator/bfs/issues/30 + + +1.* +=== + +1.7 +--- + +**April 22, 2020** + +- Fixed `-ls` printing numeric IDs instead of user/group names in large directory trees +- Cached the user and group tables for a performance boost +- Fixed interpretation of "default" ACLs +- Implemented `-s` flag to sort results + + +1.6 +--- + +**February 25, 2020** + +- Implemented `-newerXt` (explicit reference times), `-since`, `-asince`, etc. +- Fixed `-empty` to skip special files (pipes, devices, sockets, etc.) + + +1.5.2 +----- + +**January 9, 2020** + +- Fixed the build on NetBSD +- Added support for NFSv4 ACLs on FreeBSD +- Added a `+` after the file mode for files with ACLs in `-ls` +- Supported more file types (whiteouts, doors) in symbolic modes for `-ls`/`-printf %M` +- Implemented `-xattr` on FreeBSD + + +1.5.1 +----- + +**September 14, 2019** + +- Added a warning to `-mount`, since it will change behaviour in the next POSIX revision +- Added a workaround for environments that block `statx()` with `seccomp()`, like older Docker +- Fixed coloring of nonexistent leading directories +- Avoided calling `stat()` on all mount points at startup + + +1.5 +--- + +**June 27, 2019** + +- New `-xattr` predicate to find files with extended attributes +- Fixed the `-acl` implementation on macOS +- Implemented depth-first (`-S dfs`) and iterative deepening search (`-S ids`) +- Piped `-help` output into `$PAGER` by default +- Fixed crashes on some invalid `LS_COLORS` values + + +1.4.1 +----- + +**April 5, 2019** + +- Added a nicer error message when the tests are run as root +- Fixed detection of comparison expressions with signs, to match GNU find for things like `-uid ++10` +- Added support for https://no-color.org/ +- Decreased the number of `stat()` calls necessary in some cases + + +1.4 +--- + +**April 15, 2019** + +- New `-unique` option that filters out duplicate files ([#48]) +- Optimized the file coloring implementation +- Fixed the coloring implementation to match GNU ls more closely in many corner cases + - Implemented escape sequence parsing for `LS_COLORS` + - Implemented `ln=target` for coloring links like their targets + - Fixed the order of fallbacks used when some color keys are unset +- Add a workaround for incorrect file types for bind-mounted files on Linux ([#37]) + +[#48]: https://github.com/tavianator/bfs/issues/48 +[#37]: https://github.com/tavianator/bfs/issues/37 + + +1.3.3 +----- + +**February 10, 2019** + +- Fixed unpredictable behaviour for empty responses to `-ok`/`-okdir` caused by an uninitialized string +- Writing to standard output now causes `bfs` to fail if the descriptor was closed +- Fixed incomplete file coloring in error messages +- Added some data flow optimizations +- Fixed `-nogroup`/`-nouser` in big directory trees +- Added `-type w` for whiteouts, as supported by FreeBSD `find` +- Re-wrote the `-help` message and manual page + + +1.3.2 +----- + +**January 11, 2019** + +- Fixed an out-of-bounds read if LS_COLORS doesn't end with a `:` +- Allowed multiple debug flags to be specified like `-D opt,tree` + + +1.3.1 +----- + +**January 3, 2019** + +- Fixed some portability problems affecting FreeBSD + + +1.3 +--- + +**January 2, 2019** + +New features: + +- `-acl` finds files with non-trivial Access Control Lists (from FreeBSD) +- `-capable` finds files with capabilities set +- `-D all` turns on all debugging flags at once + +Fixes: + +- `LS_COLORS` handling has been improved: + - Extension colors are now case-insensitive like GNU `ls` + - `or` (orphan) and `mi` (missing) files are now treated differently + - Default colors can be unset with `di=00` or similar + - Specific colors fall back to more general colors when unspecified in more places + - `LS_COLORS` no longer needs a trailing colon +- `-ls`/`-fls` now prints the major/minor numbers for device nodes +- `-exec ;` is rejected rather than segfaulting +- `bfs` now builds on old Linux versions that require `-lrt` for POSIX timers +- For files whose access/change/modification times can't be read, `bfs` no longer fails unless those times are needed for tests +- The testsuite is now more correct and portable + + +1.2.4 +----- + +**September 24, 2018** + +- GNU find compatibility fixes for `-printf`: + - `%Y` now prints `?` if an error occurs resolving the link + - `%B` is now supported for birth/creation time (as well as `%W`/`%w`) + - All standard `strftime()` formats are supported, not just the ones from the GNU find manual +- Optimizations are now re-run if any expressions are reordered +- `-exec` and friends no longer leave zombie processes around when `exec()` fails + + +1.2.3 +----- + +**July 15, 2018** + +- Fixed `test_depth_error` on filesystems that don't fill in `d_type` +- Fixed the build on Linux architectures that don't have the `statx()` syscall (ia64, sh4) +- Fixed use of AT_EMPTY_PATH for fstatat on systems that don't support it (Hurd) +- Fixed `ARG_MAX` accounting on architectures with large pages (ppc64le) +- Fixed the build against the upcoming glibc 2.28 release that includes its own `statx()` wrapper + + +1.2.2 +----- + +**June 23, 2018** + +- Minor bug fixes: + - Fixed `-exec ... '{}' +` argument size tracking after recovering from `E2BIG` + - Fixed `-fstype` if `/proc` is available but `/etc/mtab` is not + - Fixed an uninitialized variable when given `-perm +rw...` + - Fixed some potential "error: 'path': Success" messages +- Reduced reliance on GNU coreutils in the testsuite +- Refactored and simplified the internals of `bftw()` + + +1.2.1 +----- + +**February 8, 2018** + +- Performance optimizations + + +1.2 +--- + +**January 20, 2018** + +- Added support for the `-perm +7777` syntax deprecated by GNU find (equivalent to `-perm /7777`), for compatibility with BSD finds +- Added support for file birth/creation times on platforms that report it + - `-Bmin`/`-Btime`/`-Bnewer` + - `B` flag for `-newerXY` + - `%w` and `%Wk` directives for `-printf` + - Uses the `statx(2)` system call on new enough Linux kernels +- More robustness to `E2BIG` added to the `-exec` implementation + + +1.1.4 +----- + +**October 27, 2017** + +- Added a man page +- Fixed cases where multiple actions write to the same file +- Report errors that occur when closing files/flushing streams +- Fixed "argument list too long" errors with `-exec ... '{}' +` + + +1.1.3 +----- + +**October 4, 2017** + +- Refactored the optimizer +- Implemented data flow optimizations + + +1.1.2 +----- + +**September 10, 2017** + +- Fixed `-samefile` and similar predicates when passed broken symbolic links +- Implemented `-fstype` on Solaris +- Fixed `-fstype` under musl +- Implemented `-D search` +- Implemented a cost-based optimizer + + +1.1.1 +----- + +**August 10, 2017** + +- Re-licensed under the BSD Zero Clause License +- Fixed some corner cases with `-exec` and `-ok` parsing + + +1.1 +--- + +**July 22, 2017** + +- Implemented some primaries from NetBSD `find`: + - `-exit [STATUS]` (like `-quit`, but with an optional explicit exit status) + - `-printx` (escape special characters for `xargs`) + - `-rm` (alias for `-delete`) +- Warn if `-prune` will have no effect due to `-depth` +- Handle y/n prompts according to the user's locale +- Prompt the user to correct typos without having to re-run `bfs` +- Fixed handling of paths longer than `PATH_MAX` +- Fixed spurious "Inappropriate ioctl for device" errors when redirecting `-exec ... +` output +- Fixed the handling of paths that treat a file as a directory (e.g. `a/b/c` where `a/b` is a regular file) +- Fixed an expression optimizer bug that broke command lines like `bfs -name '*' -o -print` + + +1.0.2 +----- + +**June 15, 2017** + +Bugfix release. + +- Fixed handling of \0 inside -printf format strings +- Fixed `-perm` interpretation of permcopy actions (e.g. `u=rw,g=r`) + + +1.0.1 +----- + +**May 17, 2017** + +Bugfix release. + +- Portability fixes that mostly affect GNU Hurd +- Implemented `-D exec` +- Made `-quit` not disable the implicit `-print` + + +1.0 +--- + +**April 24, 2017** + +This is the first release of bfs with support for all of GNU find's primitives. + +Changes since 0.96: + +- Implemented `-fstype` +- Implemented `-exec/-execdir ... +` +- Implemented BSD's `-X` +- Fixed the tests under Bash 3 (mostly for macOS) +- Some minor optimizations and fixes + + +0.* +=== + + +0.96 +---- + +**March 11, 2017** + +73/76 GNU find features supported. + +- Implemented -nouser and -nogroup +- Implemented -printf and -fprintf +- Implemented -ls and -fls +- Implemented -type with multiple types at once (e.g. -type f,d,l) +- Fixed 32-bit builds +- Fixed -lname on "symlinks" in Linux /proc +- Fixed -quit to take effect as soon as it's reached +- Stopped redirecting standard input from /dev/null for -ok and -okdir, as that violates POSIX +- Many test suite improvements + + +0.88 +---- + +**December 20, 2016** + +67/76 GNU find features supported. + +- Fixed the build on macOS, and some other UNIXes +- Implemented `-regex`, `-iregex`, `-regextype`, and BSD's `-E` +- Implemented `-x` (same as `-mount`/`-xdev`) from BSD +- Implemented `-mnewer` (same as `-newer`) from BSD +- Implemented `-depth N` from BSD +- Implemented `-sparse` from FreeBSD +- Implemented the `T` and `P` suffices for `-size`, for BSD compatibility +- Added support for `-gid NAME` and `-uid NAME` as in BSD + + +0.84.1 +------ + +**November 24, 2016** + +Bugfix release. + +- Fixed [#7] again +- Like GNU find, don't print warnings by default if standard input is not a terminal +- Redirect standard input from /dev/null for -ok and -okdir +- Skip . when -delete'ing +- Fixed -execdir when the root path has no slashes +- Fixed -execdir in / +- Support -perm +MODE for symbolic modes +- Fixed the build on FreeBSD + +[#7]: https://github.com/tavianator/bfs/issues/7 + + +0.84 +---- + +**October 29, 2016** + +64/76 GNU find features supported. + +- Spelling suggestion improvements +- Handle `--` +- (Untested) support for exotic file types like doors, ports, and whiteouts +- Improved robustness in the face of closed std{in,out,err} +- Fixed the build on macOS +- Implement `-ignore_readdir_race`, `-noignore_readdir_race` +- Implement `-perm` + + +0.82 +---- + +**September 4, 2016** + +62/76 GNU find features supported. + +- Rework optimization levels + - `-O1` + - Simple boolean simplification + - `-O2` + - Purity-based optimizations, allowing side-effect-free tests like `-name` or `-type` to be moved or removed + - `-O3` (**default**): + - Re-order tests to reduce the expected cost (TODO) + - `-O4` + - Aggressive optimizations that may have surprising effects on warning/error messages and runtime, but should not otherwise affect the results + - `-Ofast`: + - Always the highest level, currently the same as `-O4` +- Color files with multiple hard links correctly +- Treat `-`, `)`, and `,` as paths when required to by POSIX + - `)` and `,` are only supported before the expression begins +- Implement `-D opt` +- Implement `-D rates` +- Implement `-fprint` +- Implement `-fprint0` +- Implement BSD's `-f` +- Suggest fixes for typo'd arguments + +0.79 +---- + +**May 27, 2016** + +60/76 GNU find features supported. + +- Remove an errant debug `printf()` from `-used` +- Implement the `{} ;` variants of `-exec`, `-execdir`, `-ok`, and `-okdir` + + +0.74 +---- + +**March 12, 2016** + +56/76 GNU find features supported. + +- Color broken symlinks correctly +- Fix [#7] +- Fix `-daystart`'s rounding of midnight +- Implement (most of) `-newerXY` +- Implement `-used` +- Implement `-size` + +[#7]: https://github.com/tavianator/bfs/issues/7 + + +0.70 +---- + +**February 23, 2016** + +53/76 GNU find features supported. + +- New `make install` and `make uninstall` targets +- Squelch non-positional warnings for `-follow` +- Reduce memory footprint by as much as 64% by closing `DIR*`s earlier +- Speed up `bfs` by ~5% by using a better FD cache eviction policy +- Fix infinite recursion when evaluating `! expr` +- Optimize unused pure expressions (e.g. `-empty -a -false`) +- Optimize double-negation (e.g. `! ! -name foo`) +- Implement `-D stat` and `-D tree` +- Implement `-O` + + +0.67 +---- + +**February 14, 2016** + +Initial release. + +51/76 GNU find features supported. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 0000000..77e8e2c --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,167 @@ +Contributing +============ + +License +------- + +`bfs` is licensed under the [Zero-Clause BSD License](https://opensource.org/licenses/0BSD), a maximally permissive license. +Contributions must use the same license. + + +Building +-------- + +`bfs` uses [GNU Make](https://www.gnu.org/software/make/) as its build system. +A simple invocation of + + $ make + +should build `bfs` successfully, with no additional steps necessary. +As usual with `make`, you can run a [parallel build](https://www.gnu.org/software/make/manual/html_node/Parallel.html) with `-j`. +For example, to use all your cores, run `make -j$(nproc)`. + +### Targets + +| Command | Description | +|------------------|---------------------------------------------------------------| +| `make` | Builds just the `bfs` binary | +| `make all` | Builds everything, including the tests (but doesn't run them) | +| `make check` | Builds everything, and runs the tests | +| `make install` | Installs `bfs` (with man page, shell completions, etc.) | +| `make uninstall` | Uninstalls `bfs` | + +### Flag-like targets + +The build system provides a few shorthand targets for handy configurations: + +| Command | Description | +|----------------|-------------------------------------------------------------| +| `make release` | Build `bfs` with optimizations, LTO, and without assertions | +| `make asan` | Enable [AddressSanitizer] | +| `make lsan` | Enable [LeakSanitizer] | +| `make msan` | Enable [MemorySanitizer] | +| `make tsan` | Enable [ThreadSanitizer] | +| `make ubsan` | Enable [UndefinedBehaviorSanitizer] | +| `make gcov` | Enable [code coverage] | + +[AddressSanitizer]: https://github.com/google/sanitizers/wiki/AddressSanitizer +[LeakSanitizer]: https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#stand-alone-mode +[MemorySanitizer]: https://github.com/google/sanitizers/wiki/MemorySanitizer +[ThreadSanitizer]: https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual +[UndefinedBehaviorSanitizer]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html +[code coverage]: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html + +You can combine multiple flags and other targets (e.g. `make asan ubsan check`), but not all of them will work together. + +### Flags + +Other flags are controlled with `make` variables and/or environment variables. +Here are some of the common ones; check the [`Makefile`](/Makefile) for more. + +| Flag | Description | +|----------------------------------|---------------------------------------------| +| `CC` | The C compiler to use, e.g. `make CC=clang` | +| `CFLAGS`
`EXTRA_CFLAGS` | Override/add to the default compiler flags | +| `LDFLAGS`
`EXTRA_LDFLAGS` | Override/add to the linker flags | +| `WITH_ACL`
`WITH_ATTR`
... | Enable/disable optional dependencies | +| `TEST_FLAGS` | `tests.sh` flags for `make check` | +| `DESTDIR` | The root directory for `make install` | +| `PREFIX` | The installation prefix (default: `/usr`) | +| `MANDIR` | The man page installation directory | + +### Dependency tracking + +The build system automatically tracks header dependencies with the `-M` family of compiler options (see `DEPFLAGS` in the `Makefile`). +So if you edit a header file, `make` will rebuild the necessary object files ensuring they don't go out of sync. + +We go one step further than most build systems by tracking the flags that were used for the previous compilation. +That means you can change configurations without having to `make clean`. +For example, + + $ make + $ make release + +will build the project in debug mode and then rebuild it in release mode. + +A side effect of this may be surprising: `make check` by itself will rebuild the project in the default configuration. +To test a different configuration, you'll have to repeat it (e.g. `make release check`). + + +Testing +------- + +`bfs` comes with an extensive testsuite which can be run with + + $ make check + +Most of the testsuite is implemented in the file [`tests.sh`](/tests.sh). +This script contains hundreds of separate test cases. +Most of them are *snapshot tests* which compare `bfs`'s output to a known-good copy saved under [`tests`](/tests). + +You can pass the name of a particular test case (or a few) to run just those tests. +For example: + + $ ./tests.sh test_basic + +If you need to update the reference snapshot, pass `--update`. +It can be handy to generate the snapshot with a different `find` implementation to ensure the output is correct, for example: + + $ ./tests.sh test_basic --bfs=find --update + +But keep in mind, other `find` implementations may not be correct. +To my knowledge, no other implementation passes even the POSIX-compatible subset of the tests: + + $ ./tests.sh --bfs=find --posix + ... + tests passed: 89 + tests failed: 5 + +Run + + $ ./tests.sh --help + +for more details. + +### Validation + +A more thorough testsuite is run by the [CI](https://github.com/tavianator/bfs/actions) and to validate releases. +It builds `bfs` in multiple configurations to test for latent bugs, memory leaks, 32-bit compatibility, etc. +You can run it yourself with + + $ make distcheck + +Some of these tests require `sudo`, and will prompt for your password if necessary. + + +Hacking +------- + +`bfs` is written in [C](https://en.wikipedia.org/wiki/C_(programming_language)), specifically [C11](https://en.wikipedia.org/wiki/C11_(C_standard_revision)). +You can get a feel for the coding style by skimming the source code. +[`main.c`](/src/main.c) contains an overview of the rest of source files. +A quick summary: + +- Tabs for indentation, spaces for alignment. +- Most types and functions should be namespaced with `bfs_`. + Exceptions are made for things that could be generally useful outside of `bfs`. +- Error handling follows the C standard library conventions: return a nonzero `int` or a `NULL` pointer, with the error code in `errno`. + All failure cases should be handled, including `malloc()` failures. +- `goto` is not harmful for cleaning up in error paths. + +### Adding tests + +Both new features and bug fixes should have associated tests. +To add a test, create a new function in `tests.sh` called `test_`. +Snapshot tests use the `bfs_diff` function to automatically compare the generated and expected outputs. +For example, + +```bash +function test_something() { + bfs_diff basic -name something +} +``` + +`basic` is one of the directory trees generated for test cases; others include `links`, `loops`, `deep`, and `rainbow`. + +Run `./tests.sh test_something --update` to generate the reference snapshot (and don't forget to `git add` it). +Finally, add the test case to one of the arrays `posix_tests`, `bsd_tests`, `gnu_tests`, or `bfs_tests` depending on which `find` implementations it should be compatible with. diff --git a/docs/bfs.1 b/docs/bfs.1 new file mode 100644 index 0000000..53a9831 --- /dev/null +++ b/docs/bfs.1 @@ -0,0 +1,811 @@ +.TH BFS 1 +.SH NAME +bfs \- breadth-first search for your files +.SH SYNOPSIS +.B bfs +.RB [ flags ...] +.RI [ paths ...] +.RB [ expression ...] +.PP +flags +.RB ( \-H / \-L / \-P +etc.), +.IR paths , +and +.B expressions +may be freely mixed in any order. +.SH DESCRIPTION +.B bfs +is a breadth-first version of the UNIX +.BR find (1) +command. +.PP +.B bfs +supports almost every feature from every major +.BR find (1) +implementation, so your existing command lines should work as-is. +It also adds some features of its own, such as a more forgiving command line parser and some additional options. +.PP +Each +.I path +specified on the command line is treated as a starting path to search through. +If no paths are specified, the current directory +.RI ( . ) +is searched by default. +.PP +Like +.BR find (1), +.B bfs +interprets its arguments as a short-circuiting Boolean expression. +For example, +.PP +.nf +.RS +.B bfs \\\( \-name '*.txt' \-or \-lname '*.txt' \\\\) \-and \-print +.RE +.fi +.PP +will print the all the paths that are either .txt files or symbolic links to .txt files. +.B \-and +is implied between two consecutive expressions, so this is equivalent: +.PP +.nf +.RS +.B bfs \\\( \-name '*.txt' \-or \-lname '*.txt' \\\\) \-print +.RE +.fi +.PP +Finally, +.B \-print +is implied if no actions are specified, so this too is equivalent: +.PP +.nf +.RS +.B bfs \-name '*.txt' \-or \-lname '*.txt' +.RE +.fi +.PP +Most options that take a numeric argument +.I N +will also accept +.I \-N +or +.IR +N . +.IR \-N +means "less than +.IR N ," +and +.I +N +means "greater than +.IR N ." +.SH FLAGS +.TP +.B \-H +Follow symbolic links on the command line, but not while searching. +.TP +.B \-L +Follow all symbolic links. +.TP +.B \-P +Never follow symbolic links (the default). +.TP +.B \-E +Use extended regular expressions (same as \fB\-regextype posix-extended\fR). +.TP +.B \-X +Filter out files with +.RB non- xargs (1)-safe +names. +.TP +.B \-d +Search in post-order (same as +.BR \-depth ). +.TP +.B \-s +Visit directory entries in sorted order. +The sorting takes place within each directory separately, which makes it different from +.B bfs ... | +.BR sort , +but still provides a deterministic ordering. +.TP +.B \-x +Don't descend into other mount points (same as \fB\-xdev\fR). +.TP +\fB\-f \fIPATH\fR +Treat +.I PATH +as a path to search (useful if it begins with a dash). +.PP +.TP +\fB\-D \fIFLAG\fR +Turn on a debugging flag (see +.B \-D +.IR help ). +.PP +\fB\-O\fIN\fR +.RS +Enable optimization level +.I N +(default: +.IR 3 ). +.TP +.BI \-O 0 +Disable all optimizations. +.TP +.BI \-O 1 +Basic logical simplifications. +.TP +.BI \-O 2 +All +.BI \-O 1 +optimizations, plus dead code elimination and data flow analysis. +.TP +.BI \-O 3 +All +.BI \-O 2 +optimizations, plus re-order expressions to reduce expected cost. +.TP +\fB\-O\fI4\fR/\fB\-O\fIfast\fR +All optimizations, including aggressive optimizations that may alter the observed behavior in corner cases. +.RE +.PP +\fB\-S \fIbfs\fR|\fIdfs\fR|\fIids\fR|\fIeds\fR +.RS +Choose the search strategy. +.TP +.I bfs +Breadth-first search (the default). +.TP +.I dfs +Depth-first search. +Uses less memory than breadth-first search, but is typically slower to return relevant results. +.TP +.I ids +Iterative deepening search. +Performs repeated depth-first searches with increasing depth limits. +This gives results in the same order as breadth-first search, but with the reduced memory consumption of depth-first search. +Tends to be very slow in practice, so use it only if you absolutely need breadth-first ordering, but +.B \-S +.I bfs +consumes too much memory. +.TP +.I eds +Exponential deepening search. +A compromise between breadth- and depth-first search, which searches exponentially increasing depth ranges (e.g 0-1, 1-2, 2-4, 4-8, etc.). +Provides many of the benefits of breadth-first search with depth-first's reduced memory consumption. +Typically far faster than +.B \-S +.IR ids . +.RE +.SH OPERATORS +.TP +\fB( \fIexpression \fB)\fR +Parentheses are used for grouping expressions together. +You'll probably have to write +.B \\\\( +.I expression +.B \\\\) +to avoid the parentheses being interpreted by the shell. +.PP +\fB! \fIexpression\fR +.br +\fB\-not \fIexpression\fR +.RS +The "not" operator: returns the negation of the truth value of the +.IR expression . +You may have to write \fB\\! \fIexpression\fR to avoid \fB!\fR being interpreted by the shell. +.RE +.PP +\fIexpression\fR \fIexpression\fR +.br +\fIexpression \fB\-a \fIexpression\fR +.br +\fIexpression \fB\-and \fIexpression\fR +.RS +Short-circuiting "and" operator: if the left-hand +.I expression +is +.BR true , +returns the right-hand +.IR expression ; +otherwise, returns +.BR false . +.RE +.PP +\fIexpression \fB\-o \fIexpression\fR +.br +\fIexpression \fB\-or \fIexpression\fR +.RS +Short-circuiting "or" operator: if the left-hand +.I expression +is +.BR false , +returns the right-hand +.IR expression ; +otherwise, returns +.BR true . +.RE +.TP +\fIexpression \fB, \fIexpression\fR +The "comma" operator: evaluates the left-hand +.I expression +but discards the result, returning the right-hand +.IR expression . +.SH SPECIAL FORMS +.TP +\fB\-exclude \fIexpression\fR +Exclude all paths matching the +.I expression +from the search. +This is more powerful than +.BR \-prune , +because it applies even when the expression wouldn't otherwise be evaluated, due to +.B \-depth +or +.B \-mindepth +for example. +Exclusions are always applied before other expressions, so it may be least confusing to put them first on the command line. +.SH OPTIONS +.PP +.B \-color +.br +.B \-nocolor +.RS +Turn colors on or off (default: +.B \-color +if outputting to a terminal, +.B \-nocolor +otherwise). +.RE +.TP +.B \-daystart +Measure time relative to the start of today. +.TP +.B \-depth +Search in post-order (descendents first). +.TP +.B \-follow +Follow all symbolic links (same as +.BR \-L ). +.TP +\fB\-files0\-from \fIFILE\fR +Treat the NUL ('\\0')-separated paths in +.I FILE +as starting points for the search. +Pass +.B \-files0\-from +.I \- +to read the paths from standard input. +.PP +\fB\-ignore_readdir_race\fR +.br +\fB\-noignore_readdir_race\fR +.RS +Whether to report an error if +.B bfs +detects that the file tree is modified during the search (default: +.BR \-noignore_readdir_race ). +.RE +.PP +\fB\-maxdepth \fIN\fR +.br +\fB\-mindepth \fIN\fR +.RS +Ignore files deeper/shallower than +.IR N . +.RE +.TP +.B \-mount +Don't descend into other mount points (same as +.B \-xdev +for now, but will skip mount points entirely in the future). +.TP +.B \-nohidden +Exclude hidden files and directories. +.TP +.B \-noleaf +Ignored; for compatibility with GNU find. +.TP +\fB\-regextype \fITYPE\fR +Use +.IR TYPE -flavored +regexes (default: +.IR posix-basic ; +see +.B \-regextype +.IR help ). +.TP +.B \-status +Display a status bar while searching. +.TP +.B \-unique +Skip any files that have already been seen. +Particularly useful along with +.BR \-L . +.PP +.B \-warn +.br +.B \-nowarn +.RS +Turn on or off warnings about the command line. +.RE +.TP +.B \-xdev +Don't descend into other mount points. +.SH TESTS +.TP +.B \-acl +Find files with a non-trivial Access Control List +.RB ( acl (5)). +.PP +\fB\-amin\fR [\fI\-+\fR]\fIN\fR +.br +\fB\-Bmin\fR [\fI\-+\fR]\fIN\fR +.br +\fB\-cmin\fR [\fI\-+\fR]\fIN\fR +.br +\fB\-mmin\fR [\fI\-+\fR]\fIN\fR +.RS +Find files +.BR a ccessed/ B irthed/ c hanged/ m odified +.I N +minutes ago. +.RE +.PP +\fB\-anewer \fIFILE\fR +.br +\fB\-Bnewer \fIFILE\fR +.br +\fB\-cnewer \fIFILE\fR +.br +\fB\-mnewer \fIFILE\fR +.RS +Find files +.BR a ccessed/ B irthed/ c hanged/ m odified +more recently than +.I FILE +was modified. +.RE +.PP +\fB\-asince \fITIME\fR +.br +\fB\-Bsince \fITIME\fR +.br +\fB\-csince \fITIME\fR +.br +\fB\-msince \fITIME\fR +.RS +Find files +.BR a ccessed/ B irthed/ c hanged/ m odified +more recently than the ISO 8601-style timestamp +.IR TIME . +See +.BI \-newer XY +for examples of the timestamp format. +.RE +.PP +\fB\-atime\fR [\fI\-+\fR]\fIN\fR +.br +\fB\-Btime\fR [\fI\-+\fR]\fIN\fR +.br +\fB\-ctime\fR [\fI\-+\fR]\fIN\fR +.br +\fB\-mtime\fR [\fI\-+\fR]\fIN\fR +.RS +Find files +.BR a ccessed/ B irthed/ c hanged/ m odified +.I N +days ago. +.RE +.TP +.B \-capable +Find files with POSIX.1e +.BR capabilities (7) +set. +.TP +\fB\-depth\fR [\fI\-+\fR]\fIN\fR +Find files with depth +.IR N . +.TP +.B \-empty +Find empty files/directories. +.PP +.B \-executable +.br +.B \-readable +.br +.B \-writable +.RS +Find files the current user can execute/read/write. +.RE +.PP +.B \-false +.br +.B \-true +.RS +Always false/true. +.RE +.TP +.B \-fstype TYPE +Find files on file systems with the given +.BR TYPE . +.PP +\fB\-gid\fR [\fI\-+\fR]\fIN\fR +.br +\fB\-uid\fR [\fI\-+\fR]\fIN\fR +.RS +Find files owned by group/user ID +.IR N . +.RE +.PP +\fB\-group \fINAME\fR +.br +\fB\-user \fINAME\fR +.RS +Find files owned by the group/user +.IR NAME . +.RE +.TP +.B \-hidden +Find hidden files (those beginning with +.IR . ). +.PP +\fB\-ilname \fIGLOB\fR +.br +\fB\-iname \fIGLOB\fR +.br +\fB\-ipath \fIGLOB\fR +.br +\fB\-iregex \fIREGEX\fR +.br +\fB\-iwholename \fIGLOB\fR +.RS +Case-insensitive versions of +.BR \-lname / \-name / \-path / \-regex / \-wholename . +.RE +.TP +\fB\-inum\fR [\fI\-+\fR]\fIN\fR +Find files with inode number +.IR N . +.TP +\fB\-links\fR [\fI\-+\fR]\fIN\fR +Find files with +.I N +hard links. +.TP +\fB\-lname \fIGLOB\fR +Find symbolic links whose target matches the +.IR GLOB . +.TP +\fB\-name \fIGLOB\fR +Find files whose name matches the +.IR GLOB . +.TP +\fB\-newer \fIFILE\fR +Find files newer than +.IR FILE . +.TP +\fB\-newer\fIXY \fIREFERENCE\fR +Find files whose +.I X +time is newer than the +.I Y +time of +.IR REFERENCE . +.I X +and +.I Y +can be any of +.RI [ aBcm ] +.RI ( a ccess/ B irth/ c hange/ m odification). +.I Y +may also be +.I t +to parse +.I REFERENCE +as an ISO 8601-style timestamp. For example: +.PP +.RS +1991-12-14 +.br +1991-12-14T03:00 +.br +1991-12-14T03:00-07:00 +.br +1991-12-14T10:00Z +.RE +.PP +.B \-nogroup +.br +.B \-nouser +.RS +Find files owned by nonexistent groups/users. +.RE +.PP +\fB\-path \fIGLOB\fR +.br +\fB\-wholename \fIGLOB\fR +.RS +Find files whose entire path matches the +.IR GLOB . +.RE +.TP +\fB\-perm\fR [\fI\-\fR]\fIMODE\fR +Find files with a matching mode. +.TP +\fB\-regex \fIREGEX\fR +Find files whose entire path matches the regular expression +.IR REGEX . +.TP +\fB\-samefile \fIFILE\fR +Find hard links to +.IR FILE . +.TP +\fB\-since \fITIME\fR +Find files modified since the ISO 8601-style timestamp +.IR TIME . +See +.BI \-newer XY +for examples of the timestamp format. +.TP +\fB\-size\fR [\fI\-+\fR]\fIN\fR[\fIcwbkMGTP\fR] +Find files with the given size, in 1-byte +.IR c haracters, +2-byte +.IR w ords, +512-byte +.IR b locks +(default), or +.IR k iB/ M iB/ G iB/ T iB/ P iB. +.TP +.B \-sparse +Find files that occupy fewer disk blocks than expected. +.TP +\fB\-type\fR [\fIbcdlpfswD\fR] +Find files of the given type. +Possible types are +.IR b lock +device, +.IR c haracter +device, +.IR d irectory, +symbolic +.IR l ink, +.IR p ipe, +regular +.IR f ile, +.IR s ocket, +.IR w hiteout, +and +.IR D oor. +.TP +\fB\-used\fR [\fI\-+\fR]\fIN\fR +Find files last accessed +.I N +days after they were changed. +.TP +.B \-xattr +Find files with extended attributes +.RB ( xattr (7)). +.TP +\fB\-xattrname\fR \fINAME\fR +Find files with the extended attribute +.IR NAME . +.TP +\fB\-xtype\fR [\fIbcdlpfswD\fR] +Find files of the given type, following links when +.B \-type +would not, and vice versa. +.SH ACTIONS +.PP +.B \-delete +.br +.B \-rm +.RS +Delete any found files (implies \fB-depth\fR). +.RE +.TP +\fB\-exec \fIcommand ... {} ;\fR +Execute a command. +.TP +\fB\-exec \fIcommand ... {} +\fR +Execute a command with multiple files at once. +.TP +\fB\-ok \fIcommand ... {} ;\fR +Prompt the user whether to execute a command. +.PP +\fB\-execdir \fIcommand ... {} ;\fR +.br +\fB\-execdir \fIcommand ... {} +\fR +.br +\fB\-okdir \fIcommand ... {} ;\fR +.RS +Like +.BR \-exec / \-ok , +but run the command in the same directory as the found file(s). +.RE +.TP +\fB\-exit\fR [\fISTATUS\fR] +Exit immediately with the given status (0 if unspecified). +.PP +\fB\-fls \fIFILE\fR +.br +\fB\-fprint \fIFILE\fR +.br +\fB\-fprint0 \fIFILE\fR +.br +\fB\-fprintf \fIFILE FORMAT\fR +.RS +Like +.BR \-ls / \-print / \-print0 / \-printf , +but write to +.I FILE +instead of standard output. +.RE +.TP +.B \-ls +List files like +.B ls +.IR \-dils . +.TP +.B \-print +Print the path to the found file. +.TP +.B \-print0 +Like +.BR \-print , +but use the null character ('\\0') as a separator rather than newlines. +Useful in conjunction with +.B xargs +.IR \-0 . +.TP +\fB\-printf \fIFORMAT\fR +Print according to a format string (see +.BR find (1)). +These additional format directives are supported: +.RS +.TP +%w +The file's birth time, in the same format as %a/%c/%t. +.TP +.RI %W k +Field +.I k +of the file's birth time, in the same format as +.RI %A k /%C k /%T k . +.RE +.TP +.B \-printx +Like +.BR \-print , +but escape whitespace and quotation characters, to make the output safe for +.BR xargs (1). +Consider using +.B \-print0 +and +.B xargs +.I \-0 +instead. +.TP +.B \-prune +Don't descend into this directory. +.TP +.B \-quit +Quit immediately. +.TP +.B \-version +Print version information. +.TP +.B \-help +Print usage information. +.SH ENVIRONMENT +Certain environment variables affect the behavior of +.BR bfs . +.PP +.B LANG +.br +.B LC_* +.RS +Specifies the +.BR locale (7) +in use for various things. +.B bfs +is not (yet) translated to any languages except English, but the locale will still affect the format of printed values. +Yes/no prompts (e.g. from +.BR \-ok ) +will also be interpreted according to the current locale. +.RE +.PP +.B LS_COLORS +.br +.B BFS_COLORS +.RS +Controls the colors used when displaying file paths if +.B \-color +is enabled. +.B bfs +interprets +.B LS_COLORS +the same way GNU +.BR ls (1) +does (see +.BR dir_colors (5)). +.B BFS_COLORS +can be used to customize +.B bfs +without affecting other commands. +.RE +.TP +.B NO_COLOR +Causes +.B bfs +to default to +.B \-nocolor +if it is set (see https://no-color.org/). +.TP +.B PAGER +Specifies the pager used for +.B \-help +output. +Defaults to +.BR more (1). +.TP +.B POSIXLY_CORRECT +Makes +.B bfs +conform more strictly to the POSIX.1-2017 specification for +.BR find (1). +Currently this just disables warnings by default. +It does not disable +.BR bfs 's +various extensions to the base POSIX functionality. +.SH EXAMPLES +.TP +.B bfs +With no arguments, +.B bfs +prints all files under the current directory in breadth-first order. +.TP +.B bfs \-name '*.txt' +Prints all the .txt files under the current directory. +.B *.txt +is quoted to ensure the glob is processed by +.B bfs +rather than the shell. +.TP +\fBbfs \-name access_log \-L \fI/var\fR +Finds all files named +.B access_log +under +.IR /var , +following symbolic links. +.B bfs +allows flags and paths to appear anywhere on the command line. +.TP +\fBbfs \fI~ \fB\-not \-user $USER\fR +Prints all files in your home directory not owned by you. +.TP +.B bfs \-xtype l +Finds broken symbolic links. +.TP +.B bfs \-name config \-exclude \-name .git +Finds all files named +.BR config, +skipping every +.B .git +directory. +.TP +.B bfs \-type f \-executable \-exec strip '{}' + +Runs +.BR strip (1) +on all executable files it finds, passing it multiple files at a time. +.SH BUGS +https://github.com/tavianator/bfs/issues +.SH AUTHOR +Tavian Barnes +.PP +https://tavianator.com/projects/bfs.html +.SH SEE ALSO +.BR find (1), +.BR locate (1), +.BR xargs (1) -- cgit v1.2.3