5 kx \input texinfo @c -*-texinfo-*-
5 kx @c %**start of header
5 kx @setfilename find.info
5 kx @include version.texi
5 kx @settitle GNU Findutils @value{VERSION}
5 kx @c For double-sided printing, uncomment:
5 kx @c @setchapternewpage odd
5 kx @c %**end of header
5 kx
5 kx @iftex
5 kx @finalout
5 kx @end iftex
5 kx
5 kx @dircategory Basics
5 kx @direntry
5 kx * Finding files: (find). Operating on files matching certain criteria.
5 kx @end direntry
5 kx
5 kx @dircategory Individual utilities
5 kx @direntry
5 kx * find: (find)Invoking find. Finding and acting on files.
5 kx * locate: (find)Invoking locate. Finding files in a database.
5 kx * updatedb: (find)Invoking updatedb. Building the locate database.
5 kx * xargs: (find)Invoking xargs. Operating on many files.
5 kx @end direntry
5 kx
5 kx @copying
5 kx This manual documents version @value{VERSION} of the GNU utilities for finding
5 kx files that match certain criteria and performing various operations on them.
5 kx
5 kx Copyright @copyright{} 1994--2021 Free Software Foundation, Inc.
5 kx
5 kx @quotation
5 kx Permission is granted to copy, distribute and/or modify this document
5 kx under the terms of the GNU Free Documentation License, Version 1.3 or
5 kx any later version published by the Free Software Foundation; with no
5 kx Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
5 kx A copy of the license is included in the section entitled
5 kx ``GNU Free Documentation License''.
5 kx @end quotation
5 kx @end copying
5 kx
5 kx @titlepage
5 kx @title GNU Findutils
5 kx @subtitle Finding files
5 kx @subtitle version @value{VERSION}, @value{UPDATED}
5 kx @author by David MacKenzie and James Youngman
5 kx
5 kx @page
5 kx @vskip 0pt plus 1filll
5 kx @insertcopying
5 kx @end titlepage
5 kx
5 kx @contents
5 kx
5 kx @ifnottex
5 kx @node Top
5 kx @top GNU Findutils
5 kx @comment node-name, next, previous, up
5 kx @insertcopying
5 kx @end ifnottex
5 kx
5 kx @c The master menu, created with texinfo-master-menu, goes here.
5 kx
5 kx @menu
5 kx * Introduction:: Summary of the tasks this manual describes.
5 kx * Finding Files:: Finding files that match certain criteria.
5 kx * Actions:: Doing things to files you have found.
5 kx * Databases:: Maintaining file name databases.
5 kx * File Permissions:: How to control access to files.
5 kx * Date input formats:: Specifying literal times.
5 kx * Configuration:: Options you can select at compile time.
5 kx * Reference:: Summary of how to invoke the programs.
5 kx * Common Tasks:: Solutions to common real-world problems.
5 kx * Worked Examples:: Examples demonstrating more complex points.
5 kx * Security Considerations:: Security issues relating to findutils.
5 kx * Error Messages:: Explanations of some messages you might see.
5 kx * GNU Free Documentation License:: Copying and sharing this manual.
5 kx * Primary Index:: The components of @code{find} expressions.
5 kx @end menu
5 kx
5 kx @node Introduction
5 kx @chapter Introduction
5 kx
5 kx This manual shows how to find files that meet criteria you specify,
5 kx and how to perform various actions on the files that you find. The
5 kx principal programs that you use to perform these tasks are
5 kx @code{find}, @code{locate}, and @code{xargs}. Some of the examples in
5 kx this manual use capabilities specific to the GNU versions of those
5 kx programs.
5 kx
5 kx GNU @code{find} was originally written by Eric Decker, with
5 kx enhancements by David MacKenzie, Jay Plett, and Tim Wood. GNU
5 kx @code{xargs} was originally written by Mike Rendell, with enhancements
5 kx by David MacKenzie. GNU @code{locate} and its associated utilities
5 kx were originally written by James Woods, with enhancements by David
5 kx MacKenzie. The idea for @samp{find -print0} and @samp{xargs -0} came
5 kx from Dan Bernstein. The current maintainer of GNU findutils (and this
5 kx manual) is James Youngman. Many other people have contributed bug
5 kx fixes, small improvements, and helpful suggestions. Thanks!
5 kx
5 kx To report a bug in GNU findutils, please use the form on the Savannah
5 kx web site at
5 kx @code{https://savannah.gnu.org/bugs/?group=findutils}. Reporting bugs
5 kx this way means that you will then be able to track progress in fixing
5 kx the problem.
5 kx
5 kx If you don't have web access, you can also just send mail to the
5 kx mailing list. The mailing list @email{bug-findutils@@gnu.org} carries
5 kx discussion of bugs in findutils, questions and answers about the
5 kx software and discussion of the development of the programs. To join
5 kx the list, send email to @email{bug-findutils-request@@gnu.org}.
5 kx
5 kx Please read any relevant sections of this manual before asking for
5 kx help on the mailing list. You may also find it helpful to read the
5 kx NON-BUGS section of the @code{find} manual page.
5 kx
5 kx If you ask for help on the mailing list, people will be able to help
5 kx you much more effectively if you include the following things:
5 kx
5 kx @itemize @bullet
5 kx @item The version of the software you are running. You can find this
5 kx out by running @samp{locate --version}.
5 kx @item What you were trying to do
5 kx @item The @emph{exact} command line you used
5 kx @item The @emph{exact} output you got (if this is very long, try to
5 kx find a smaller example which exhibits the same problem)
5 kx @item The output you expected to get
5 kx @end itemize
5 kx
5 kx It may also be the case that the bug you are describing has already
5 kx been fixed, if it is a bug. Please check the most recent findutils
5 kx releases at @url{ftp://ftp.gnu.org/gnu/findutils} and, if possible,
5 kx the development branch at @url{ftp://alpha.gnu.org/gnu/findutils}.
5 kx If you take the time to check that your bug still exists in current
5 kx releases, this will greatly help people who want to help you solve
5 kx your problem. Please also be aware that if you obtained findutils as
5 kx part of the GNU/Linux 'distribution', the distributions often lag
5 kx seriously behind findutils releases, even the stable release. Please
5 kx check the GNU FTP site.
5 kx
5 kx @menu
5 kx * Scope::
5 kx * Overview::
5 kx @end menu
5 kx
5 kx @node Scope
5 kx @section Scope
5 kx
5 kx For brevity, the word @dfn{file} in this manual means a regular file,
5 kx a directory, a symbolic link, or any other kind of node that has a
5 kx directory entry. A directory entry is also called a @dfn{file name}.
5 kx A file name may contain some, all, or none of the directories in a
5 kx path that leads to the file. These are all examples of what this
5 kx manual calls ``file names'':
5 kx
5 kx @example
5 kx parser.c
5 kx README
5 kx ./budget/may-94.sc
5 kx fred/.cshrc
5 kx /usr/local/include/termcap.h
5 kx @end example
5 kx
5 kx A @dfn{directory tree} is a directory and the files it contains, all
5 kx of its subdirectories and the files they contain, etc. It can also be
5 kx a single non-directory file.
5 kx
5 kx These programs enable you to find the files in one or more directory
5 kx trees that:
5 kx
5 kx @itemize @bullet
5 kx @item
5 kx have names that contain certain text or match a certain pattern;
5 kx @item
5 kx are links to certain files;
5 kx @item
5 kx were last used during a certain period of time;
5 kx @item
5 kx are within a certain size range;
5 kx @item
5 kx are of a certain type (regular file, directory, symbolic link, etc.);
5 kx @item
5 kx are owned by a certain user or group;
5 kx @item
5 kx have certain access permissions or special mode bits;
5 kx @item
5 kx contain text that matches a certain pattern;
5 kx @item
5 kx are within a certain depth in the directory tree;
5 kx @item
5 kx or some combination of the above.
5 kx @end itemize
5 kx
5 kx Once you have found the files you're looking for (or files that are
5 kx potentially the ones you're looking for), you can do more to them than
5 kx simply list their names. You can get any combination of the files'
5 kx attributes, or process the files in many ways, either individually or
5 kx in groups of various sizes. Actions that you might want to perform on
5 kx the files you have found include, but are not limited to:
5 kx
5 kx @itemize @bullet
5 kx @item
5 kx view or edit
5 kx @item
5 kx store in an archive
5 kx @item
5 kx remove or rename
5 kx @item
5 kx change access permissions
5 kx @item
5 kx classify into groups
5 kx @end itemize
5 kx
5 kx This manual describes how to perform each of those tasks, and more.
5 kx
5 kx @node Overview
5 kx @section Overview
5 kx
5 kx The principal programs used for making lists of files that match given
5 kx criteria and running commands on them are @code{find}, @code{locate},
5 kx and @code{xargs}. An additional command, @code{updatedb}, is used by
5 kx system administrators to create databases for @code{locate} to use.
5 kx
5 kx @code{find} searches for files in a directory hierarchy and prints
5 kx information about the files it found. It is run like this:
5 kx
5 kx @example
5 kx find @r{[}@var{file}@dots{}@r{]} @r{[}@var{expression}@r{]}
5 kx @end example
5 kx
5 kx @noindent
5 kx Here is a typical use of @code{find}. This example prints the names
5 kx of all files in the directory tree rooted in @file{/usr/src} whose
5 kx name ends with @samp{.c} and that are larger than 100 KiB.
5 kx @example
5 kx find /usr/src -name '*.c' -size +100k -print
5 kx @end example
5 kx
5 kx Notice that the wildcard must be enclosed in quotes in order to
5 kx protect it from expansion by the shell.
5 kx
5 kx @code{locate} searches special file name databases for file names that
5 kx match patterns. The system administrator runs the @code{updatedb}
5 kx program to create the databases. @code{locate} is run like this:
5 kx
5 kx @example
5 kx locate @r{[}@var{option}@dots{}@r{]} @var{pattern}@dots{}
5 kx @end example
5 kx
5 kx @noindent
5 kx This example prints the names of all files in the default file name
5 kx database whose name ends with @samp{Makefile} or @samp{makefile}.
5 kx Which file names are stored in the database depends on how the system
5 kx administrator ran @code{updatedb}.
5 kx @example
5 kx locate '*[Mm]akefile'
5 kx @end example
5 kx
5 kx The name @code{xargs}, pronounced EX-args, means ``combine
5 kx arguments.'' @code{xargs} builds and executes command lines by
5 kx gathering together arguments it reads on the standard input. Most
5 kx often, these arguments are lists of file names generated by
5 kx @code{find}. @code{xargs} is run like this:
5 kx
5 kx @example
5 kx xargs @r{[}@var{option}@dots{}@r{]} @r{[}@var{command} @r{[}@var{initial-arguments}@r{]}@r{]}
5 kx @end example
5 kx
5 kx @noindent
5 kx The following command searches the files listed in the file
5 kx @file{file-list} and prints all of the lines in them that contain the
5 kx word @samp{typedef}.
5 kx @example
5 kx xargs grep typedef < file-list
5 kx @end example
5 kx
5 kx @node Finding Files
5 kx @chapter Finding Files
5 kx
5 kx By default, @code{find} prints to the standard output the names of the
5 kx files that match the given criteria. @xref{Actions}, for how to get
5 kx more information about the matching files.
5 kx
5 kx
5 kx @menu
5 kx * find Expressions::
5 kx * Name::
5 kx * Links::
5 kx * Time::
5 kx * Size::
5 kx * Type::
5 kx * Owner::
5 kx * Mode Bits::
5 kx * Contents::
5 kx * Directories::
5 kx * Filesystems::
5 kx * Combining Primaries With Operators::
5 kx @end menu
5 kx
5 kx @node find Expressions
5 kx @section @code{find} Expressions
5 kx
5 kx The expression that @code{find} uses to select files consists of one
5 kx or more @dfn{primaries}, each of which is a separate command line
5 kx argument to @code{find}. @code{find} evaluates the expression each
5 kx time it processes a file. An expression can contain any of the
5 kx following types of primaries:
5 kx
5 kx @table @dfn
5 kx @item options
5 kx affect overall operation rather than the processing of a specific
5 kx file;
5 kx @item tests
5 kx return a true or false value, depending on the file's attributes;
5 kx @item actions
5 kx have side effects and return a true or false value; and
5 kx @item operators
5 kx connect the other arguments and affect when and whether they are
5 kx evaluated.
5 kx @end table
5 kx
5 kx You can omit the operator between two primaries; it defaults to
5 kx @samp{-and}. @xref{Combining Primaries With Operators}, for ways to
5 kx connect primaries into more complex expressions.
5 kx
5 kx The @samp{-print} action is performed on all files for which the
5 kx entire expression is true (@pxref{Print File Name}), unless the
5 kx expression contains an action other than @samp{-prune} or
5 kx @samp{-quit}. Actions which inhibit the default @samp{-print} are
5 kx @samp{-delete}, @samp{-exec}, @samp{-execdir}, @samp{-ok},
5 kx @samp{-okdir}, @samp{-fls}, @samp{-fprint}, @samp{-fprintf},
5 kx @samp{-ls}, @samp{-print} and @samp{-printf}.
5 kx
5 kx Options take effect immediately, rather than being evaluated for each
5 kx file when their place in the expression is reached. Therefore, for
5 kx clarity, it is best to place them at the beginning of the expression.
5 kx There are two exceptions to this; @samp{-daystart} and @samp{-follow}
5 kx have different effects depending on where in the command line they
5 kx appear. This can be confusing, so it's best to keep them at the
5 kx beginning, too.
5 kx
5 kx Many of the primaries take arguments, which immediately follow them in
5 kx the next command line argument to @code{find}. Some arguments are
5 kx file names, patterns, or other strings; others are numbers. Numeric
5 kx arguments can be specified as
5 kx
5 kx @table @code
5 kx @item +@var{n}
5 kx for greater than @var{n},
5 kx @item -@var{n}
5 kx for less than @var{n},
5 kx @item @var{n}
5 kx for exactly @var{n}.
5 kx @end table
5 kx
5 kx
5 kx @node Name
5 kx @section Name
5 kx
5 kx Here are ways to search for files whose name matches a certain
5 kx pattern. @xref{Shell Pattern Matching}, for a description of the
5 kx @var{pattern} arguments to these tests.
5 kx
5 kx Each of these tests has a case-sensitive version and a
5 kx case-insensitive version, whose name begins with @samp{i}. In a
5 kx case-insensitive comparison, the patterns @samp{fo*} and @samp{F??}
5 kx match the file names @file{Foo}, @samp{FOO}, @samp{foo}, @samp{fOo},
5 kx etc.
5 kx
5 kx @menu
5 kx * Base Name Patterns::
5 kx * Full Name Patterns::
5 kx * Fast Full Name Search::
5 kx * Shell Pattern Matching:: Wildcards used by these programs.
5 kx @end menu
5 kx
5 kx @node Base Name Patterns
5 kx @subsection Base Name Patterns
5 kx
5 kx @deffn Test -name pattern
5 kx @deffnx Test -iname pattern
5 kx True if the base of the file name (the path with the leading
5 kx directories removed) matches shell pattern @var{pattern}. For
5 kx @samp{-iname}, the match is case-insensitive.@footnote{Because we
5 kx need to perform case-insensitive matching, the GNU fnmatch
5 kx implementation is always used; if the C library includes the GNU
5 kx implementation, we use that and otherwise we use the one from gnulib}
5 kx To ignore a whole directory tree, use @samp{-prune}
5 kx (@pxref{Directories}). As an example, to find Texinfo source files in
5 kx @file{/usr/local/doc}:
5 kx
5 kx @example
5 kx find /usr/local/doc -name '*.texi'
5 kx @end example
5 kx
5 kx Notice that the wildcard must be enclosed in quotes in order to
5 kx protect it from expansion by the shell.
5 kx
5 kx As of findutils version 4.2.2, patterns for @samp{-name} and
5 kx @samp{-iname} match a file name with a leading @samp{.}. For
5 kx example the command @samp{find /tmp -name \*bar} match the file
5 kx @file{/tmp/.foobar}. Braces within the pattern (@samp{@{@}}) are not
5 kx considered to be special (that is, @code{find . -name 'foo@{1,2@}'}
5 kx matches a file named @file{foo@{1,2@}}, not the files @file{foo1} and
5 kx @file{foo2}.
5 kx
5 kx Because the leading directories are removed, the file names considered
5 kx for a match with @samp{-name} will never include a slash, so
5 kx @samp{-name a/b} will never match anything (you probably need to use
5 kx @samp{-path} instead).
5 kx @end deffn
5 kx
5 kx
5 kx @node Full Name Patterns
5 kx @subsection Full Name Patterns
5 kx
5 kx @deffn Test -path pattern
5 kx @deffnx Test -wholename pattern
5 kx True if the entire file name, starting with the command line argument
5 kx under which the file was found, matches shell pattern @var{pattern}.
5 kx To ignore a whole directory tree, use @samp{-prune} rather than
5 kx checking every file in the tree (@pxref{Directories}). The ``entire
5 kx file name'' as used by @code{find} starts with the starting-point
5 kx specified on the command line, and is not converted to an absolute
5 kx pathname, so for example @code{cd /; find tmp -wholename /tmp} will
5 kx never match anything.
5 kx
5 kx Find compares the @samp{-path} argument with the concatenation of a
5 kx directory name and the base name of the file it's considering.
5 kx Since the concatenation will never end with a slash, @samp{-path}
5 kx arguments ending in @samp{/} will match nothing (except perhaps a
5 kx start point specified on the command line).
5 kx
5 kx The name @samp{-wholename} is GNU-specific, but @samp{-path} is more
5 kx portable; it is supported by HP-UX @code{find} and is part of the
5 kx POSIX 2008 standard.
5 kx
5 kx @end deffn
5 kx
5 kx @deffn Test -ipath pattern
5 kx @deffnx Test -iwholename pattern
5 kx These tests are like @samp{-wholename} and @samp{-path}, but the match
5 kx is case-insensitive.
5 kx @end deffn
5 kx
5 kx
5 kx In the context of the tests @samp{-path}, @samp{-wholename},
5 kx @samp{-ipath} and @samp{-wholename}, a ``full path'' is the name of
5 kx all the directories traversed from @code{find}'s start point to the
5 kx file being tested, followed by the base name of the file itself.
5 kx These paths are often not absolute paths; for example
5 kx
5 kx @example
5 kx $ cd /tmp
5 kx $ mkdir -p foo/bar/baz
5 kx $ find foo -path foo/bar -print
5 kx foo/bar
5 kx $ find foo -path /tmp/foo/bar -print
5 kx $ find /tmp/foo -path /tmp/foo/bar -print
5 kx /tmp/foo/bar
5 kx @end example
5 kx
5 kx Notice that the second @code{find} command prints nothing, even though
5 kx @file{/tmp/foo/bar} exists and was examined by @code{find}.
5 kx
5 kx Unlike file name expansion on the command line, a @samp{*} in the pattern
5 kx will match both @samp{/} and leading dots in file names:
5 kx
5 kx @example
5 kx $ find . -path '*f'
5 kx ./quux/bar/baz/f
5 kx $ find . -path '*/*config'
5 kx ./quux/bar/baz/.config
5 kx @end example
5 kx
5 kx
5 kx @deffn Test -regex expr
5 kx @deffnx Test -iregex expr
5 kx True if the entire file name matches regular expression @var{expr}.
5 kx This is a match on the whole path, not a search. For example, to
5 kx match a file named @file{./fubar3}, you can use the regular expression
5 kx @samp{.*bar.} or @samp{.*b.*3}, but not @samp{f.*r3}. @xref{Regexps,
5 kx , Syntax of Regular Expressions, emacs, The GNU Emacs Manual}, for a
5 kx description of the syntax of regular expressions. For @samp{-iregex},
5 kx the match is case-insensitive.
5 kx
5 kx As for @samp{-path}, the candidate file name never ends with a slash,
5 kx so regular expressions which only match something that ends in slash
5 kx will always fail.
5 kx
5 kx There are several varieties of regular expressions; by default this
5 kx test uses POSIX basic regular expressions, but this can be changed
5 kx with the option @samp{-regextype}.
5 kx @end deffn
5 kx
5 kx @deffn Option -regextype name
5 kx This option controls the variety of regular expression syntax
5 kx understood by the @samp{-regex} and @samp{-iregex} tests. This option
5 kx is positional; that is, it only affects regular expressions which
5 kx occur later in the command line. If this option is not given, GNU
5 kx Emacs regular expressions are assumed. Currently-implemented types
5 kx are
5 kx
5 kx
5 kx @table @samp
5 kx @item emacs
5 kx Regular expressions compatible with GNU Emacs; this is also the
5 kx default behaviour if this option is not used.
5 kx @item posix-awk
5 kx Regular expressions compatible with the POSIX awk command (not GNU awk)
5 kx @item posix-basic
5 kx POSIX Basic Regular Expressions.
5 kx @item posix-egrep
5 kx Regular expressions compatible with the POSIX egrep command
5 kx @item posix-extended
5 kx POSIX Extended Regular Expressions
5 kx @end table
5 kx
5 kx @ref{Regular Expressions} for more information on the regular
5 kx expression dialects understood by GNU findutils.
5 kx
5 kx
5 kx @end deffn
5 kx
5 kx @node Fast Full Name Search
5 kx @subsection Fast Full Name Search
5 kx
5 kx To search for files by name without having to actually scan the
5 kx directories on the disk (which can be slow), you can use the
5 kx @code{locate} program. For each shell pattern you give it,
5 kx @code{locate} searches one or more databases of file names and
5 kx displays the file names that contain the pattern. @xref{Shell Pattern
5 kx Matching}, for details about shell patterns.
5 kx
5 kx If a pattern is a plain string -- it contains no
5 kx metacharacters -- @code{locate} displays all file names in the database
5 kx that contain that string. If a pattern contains
5 kx metacharacters, @code{locate} only displays file names that match the
5 kx pattern exactly. As a result, patterns that contain metacharacters
5 kx should usually begin with a @samp{*}, and will most often end with one
5 kx as well. The exceptions are patterns that are intended to explicitly
5 kx match the beginning or end of a file name.
5 kx
5 kx If you only want @code{locate} to match against the last component of
5 kx the file names (the ``base name'' of the files) you can use the
5 kx @samp{--basename} option. The opposite behaviour is the default, but
5 kx can be selected explicitly by using the option @samp{--wholename}.
5 kx
5 kx The command
5 kx @example
5 kx locate @var{pattern}
5 kx @end example
5 kx
5 kx is almost equivalent to
5 kx @example
5 kx find @var{directories} -name @var{pattern}
5 kx @end example
5 kx
5 kx where @var{directories} are the directories for which the file name
5 kx databases contain information. The differences are that the
5 kx @code{locate} information might be out of date, and that @code{locate}
5 kx handles wildcards in the pattern slightly differently than @code{find}
5 kx (@pxref{Shell Pattern Matching}).
5 kx
5 kx The file name databases contain lists of files that were on the system
5 kx when the databases were last updated. The system administrator can
5 kx choose the file name of the default database, the frequency with which
5 kx the databases are updated, and the directories for which they contain
5 kx entries.
5 kx
5 kx Here is how to select which file name databases @code{locate}
5 kx searches. The default is system-dependent. At the time this document
5 kx was generated, the default was @file{@value{LOCATE_DB}}.
5 kx
5 kx @table @code
5 kx @item --database=@var{path}
5 kx @itemx -d @var{path}
5 kx Instead of searching the default file name database, search the file
5 kx name databases in @var{path}, which is a colon-separated list of
5 kx database file names. You can also use the environment variable
5 kx @code{LOCATE_PATH} to set the list of database files to search. The
5 kx option overrides the environment variable if both are used.
5 kx @end table
5 kx
5 kx GNU @code{locate} can read file name databases generated by the
5 kx @code{slocate} package. However, these generally contain a list of
5 kx all the files on the system, and so when using this database,
5 kx @code{locate} will produce output only for files which are accessible
5 kx to you. @xref{Invoking locate}, for a description of the
5 kx @samp{--existing} option which is used to do this.
5 kx
5 kx The @code{updatedb} program can also generate database in a format
5 kx compatible with @code{slocate}. @xref{Invoking updatedb}, for a
5 kx description of its @samp{--dbformat} and @samp{--output} options.
5 kx
5 kx
5 kx @node Shell Pattern Matching
5 kx @subsection Shell Pattern Matching
5 kx
5 kx @code{find} and @code{locate} can compare file names, or parts of file
5 kx names, to shell patterns. A @dfn{shell pattern} is a string that may
5 kx contain the following special characters, which are known as
5 kx @dfn{wildcards} or @dfn{metacharacters}.
5 kx
5 kx You must quote patterns that contain metacharacters to prevent the
5 kx shell from expanding them itself. Double and single quotes both work;
5 kx so does escaping with a backslash.
5 kx
5 kx @table @code
5 kx @item *
5 kx Matches any zero or more characters.
5 kx
5 kx @item ?
5 kx Matches any one character.
5 kx
5 kx @item [@var{string}]
5 kx Matches exactly one character that is a member of the string
5 kx @var{string}. This is called a @dfn{character class}. As a
5 kx shorthand, @var{string} may contain ranges, which consist of two
5 kx characters with a dash between them. For example, the class
5 kx @samp{[a-z0-9_]} matches a lowercase letter, a number, or an
5 kx underscore. You can negate a class by placing a @samp{!} or @samp{^}
5 kx immediately after the opening bracket. Thus, @samp{[^A-Z@@]} matches
5 kx any character except an uppercase letter or an at sign.
5 kx
5 kx @item \
5 kx Removes the special meaning of the character that follows it. This
5 kx works even in character classes.
5 kx @end table
5 kx
5 kx In the @code{find} tests that do shell pattern matching (@samp{-name},
5 kx @samp{-wholename}, etc.), wildcards in the pattern will match a
5 kx @samp{.} at the beginning of a file name. This is also the case for
5 kx @code{locate}. Thus, @samp{find -name '*macs'} will match a file
5 kx named @file{.emacs}, as will @samp{locate '*macs'}.
5 kx
5 kx Slash characters have no special significance in the shell pattern
5 kx matching that @code{find} and @code{locate} do, unlike in the shell,
5 kx in which wildcards do not match them. Therefore, a pattern
5 kx @samp{foo*bar} can match a file name @samp{foo3/bar}, and a pattern
5 kx @samp{./sr*sc} can match a file name @samp{./src/misc}.
5 kx
5 kx If you want to locate some files with the @samp{locate} command but
5 kx don't need to see the full list you can use the @samp{--limit} option
5 kx to see just a small number of results, or the @samp{--count} option to
5 kx display only the total number of matches.
5 kx
5 kx @node Links
5 kx @section Links
5 kx
5 kx There are two ways that files can be linked together. @dfn{Symbolic
5 kx links} are a special type of file whose contents are a portion of the
5 kx name of another file. @dfn{Hard links} are multiple directory entries
5 kx for one file; the file names all have the same index node
5 kx (@dfn{inode}) number on the disk.
5 kx
5 kx @menu
5 kx * Symbolic Links::
5 kx * Hard Links::
5 kx @end menu
5 kx
5 kx @node Symbolic Links
5 kx @subsection Symbolic Links
5 kx
5 kx Symbolic links are names that reference other files. GNU @code{find}
5 kx will handle symbolic links in one of two ways; firstly, it can
5 kx dereference the links for you - this means that if it comes across a
5 kx symbolic link, it examines the file that the link points to, in order
5 kx to see if it matches the criteria you have specified. Secondly, it
5 kx can check the link itself in case you might be looking for the actual
5 kx link. If the file that the symbolic link points to is also within the
5 kx directory hierarchy you are searching with the @code{find} command,
5 kx you may not see a great deal of difference between these two
5 kx alternatives.
5 kx
5 kx By default, @code{find} examines symbolic links themselves when it
5 kx finds them (and, if it later comes across the linked-to file, it will
5 kx examine that, too). If you would prefer @code{find} to dereference
5 kx the links and examine the file that each link points to, specify the
5 kx @samp{-L} option to @code{find}. You can explicitly specify the
5 kx default behaviour by using the @samp{-P} option. The @samp{-H}
5 kx option is a half-way-between option which ensures that any symbolic
5 kx links listed on the command line are dereferenced, but other symbolic
5 kx links are not.
5 kx
5 kx Symbolic links are different from ``hard links'' in the sense that you
5 kx need permission to search the directories
5 kx in the linked-to file name to
5 kx dereference the link. This can mean that even if you specify the
5 kx @samp{-L} option, @code{find} may not be able to determine the
5 kx properties of the file that the link points to (because you don't have
5 kx sufficient permission). In this situation, @code{find} uses the
5 kx properties of the link itself. This also occurs if a symbolic link
5 kx exists but points to a file that is missing.
5 kx
5 kx The options controlling the behaviour of @code{find} with respect to
5 kx links are as follows:
5 kx
5 kx @table @samp
5 kx @item -P
5 kx @code{find} does not dereference symbolic links at all. This is the
5 kx default behaviour. This option must be specified before any of the
5 kx file names on the command line.
5 kx @item -H
5 kx @code{find} does not dereference symbolic links (except in the case of
5 kx file names on the command line, which are dereferenced). If a
5 kx symbolic link cannot be dereferenced, the information for the symbolic
5 kx link itself is used. This option must be specified before any of the
5 kx file names on the command line.
5 kx @item -L
5 kx @code{find} dereferences symbolic links where possible, and where this
5 kx is not possible it uses the properties of the symbolic link itself.
5 kx This option must be specified before any of the file names on the
5 kx command line. Use of this option also implies the same behaviour as
5 kx the @samp{-noleaf} option. If you later use the @samp{-H} or
5 kx @samp{-P} options, this does not turn off @samp{-noleaf}.
5 kx
5 kx Actions that can cause symbolic links to become broken while
5 kx @samp{find} is executing (for example @samp{-delete}) can give rise to
5 kx confusing behaviour. Take for example the command line
5 kx @samp{find -L . -type d -delete}. This will delete empty
5 kx directories. If a subtree includes only directories and symbolic
5 kx links to directoires, this command may still not successfully delete
5 kx it, since deletion of the target of the symbolic link will cause the
5 kx symbolic link to become broken and @samp{-type d} is false for broken
5 kx symbolic links.
5 kx
5 kx @item -follow
5 kx This option forms part of the ``expression'' and must be specified
5 kx after the file names, but it is otherwise equivalent to @samp{-L}.
5 kx The @samp{-follow} option affects only those tests which appear after
5 kx it on the command line. This option is deprecated. Where possible,
5 kx you should use @samp{-L} instead.
5 kx @end table
5 kx
5 kx The following differences in behaviour occur when the @samp{-L} option
5 kx is used:
5 kx
5 kx @itemize @bullet
5 kx @item
5 kx @code{find} follows symbolic links to directories when searching
5 kx directory trees.
5 kx @item
5 kx @samp{-lname} and @samp{-ilname} always return false (unless they
5 kx happen to match broken symbolic links).
5 kx @item
5 kx @samp{-type} reports the types of the files that symbolic links point
5 kx to. This means that in combination with @samp{-L}, @samp{-type l}
5 kx will be true only for broken symbolic links. To check for symbolic
5 kx links when @samp{-L} has been specified, use @samp{-xtype l}.
5 kx @item
5 kx Implies @samp{-noleaf} (@pxref{Directories}).
5 kx @end itemize
5 kx
5 kx If the @samp{-L} option or the @samp{-H} option is used,
5 kx the file names used as arguments to @samp{-newer}, @samp{-anewer}, and
5 kx @samp{-cnewer} are dereferenced and the timestamp from the pointed-to
5 kx file is used instead (if possible -- otherwise the timestamp from the
5 kx symbolic link is used).
5 kx
5 kx @deffn Test -lname pattern
5 kx @deffnx Test -ilname pattern
5 kx True if the file is a symbolic link whose contents match shell pattern
5 kx @var{pattern}. For @samp{-ilname}, the match is case-insensitive.
5 kx @xref{Shell Pattern Matching}, for details about the @var{pattern}
5 kx argument. If the @samp{-L} option is in effect, this test will always
5 kx return false for symbolic links unless they are broken. So, to list
5 kx any symbolic links to @file{sysdep.c} in the current directory and its
5 kx subdirectories, you can do:
5 kx
5 kx @example
5 kx find . -lname '*sysdep.c'
5 kx @end example
5 kx @end deffn
5 kx
5 kx @node Hard Links
5 kx @subsection Hard Links
5 kx
5 kx Hard links allow more than one name to refer to the same file on a
5 kx file system, i.e., to the same inode. To find all the names which refer
5 kx to the same file as @var{name}, use @samp{-samefile NAME}.
5 kx
5 kx @deffn Test -samefile NAME
5 kx True if the file is a hard link to the same inode as @var{name}.
5 kx This implies that @var{name} and the file reside on the same file system,
5 kx i.e., they have the same device number.
5 kx
5 kx Unless the @samp{-L} option is also given to follow symbolic links, one may
5 kx confine the search to one file system by using the @samp{-xdev} option.
5 kx This is useful because hard links cannot point outside a single file system,
5 kx so this can cut down on needless searching.
5 kx
5 kx If the @samp{-L} option is in effect, then dereferencing of symbolic links
5 kx applies both to the @var{name} argument of the @samp{-samefile} primary and
5 kx to each file examined during the traversal of the directory hierarchy.
5 kx Therefore, @samp{find -L -samefile NAME} will find both hard links and
5 kx symbolic links pointing to the file referenced by @var{name}.
5 kx @end deffn
5 kx
5 kx @command{find} also allows searching for files by inode number.
5 kx
5 kx This can occasionally be useful in diagnosing problems with file systems;
5 kx for example, @command{fsck} and @command{lsof} tend to print inode numbers.
5 kx Inode numbers also occasionally turn up in log messages for some types of
5 kx software.
5 kx
5 kx You can learn a file's inode number and the number of links to it by
5 kx running @samp{ls -li}, @samp{stat} or @samp{find -ls}.
5 kx
5 kx You can search for hard links to inode number NUM by using @samp{-inum
5 kx NUM}. If there are any file system mount points below the directory
5 kx where you are starting the search, use the @samp{-xdev} option unless
5 kx you are also using the @samp{-L} option. Using @samp{-xdev} saves
5 kx needless searching, since hard links to a file must be on the
5 kx same file system. @xref{Filesystems}.
5 kx
5 kx @deffn Test -inum n
5 kx True if the file has inode number @var{n}. The @samp{+} and @samp{-} qualifiers
5 kx also work, though these are rarely useful.
5 kx
5 kx Please note that the @samp{-inum} primary simply compares the inode number
5 kx against the given @var{n}.
5 kx This means that a search for a certain inode number in several file systems
5 kx may return several files with that inode number, but as each file system has
5 kx its own device number, those files are not necessarily hard links to the
5 kx same file.
5 kx
5 kx Therefore, it is much of the time easier to use @samp{-samefile} rather than
5 kx this option.
5 kx @end deffn
5 kx
5 kx @command{find} also allows searching for files that have a certain number of
5 kx links, with @samp{-links}.
5 kx
5 kx A directory normally has at least two hard links: the entry named in its parent
5 kx directory, and the @file{.} entry inside of the directory.
5 kx If a directory has subdirectories, each of those also has a hard link called
5 kx @file{..} to its parent directory.
5 kx
5 kx The @file{.} and @file{..} directory entries are not normally searched unless
5 kx they are mentioned on the @code{find} command line.
5 kx
5 kx @deffn Test -links n
5 kx File has @var{n} hard links.
5 kx @end deffn
5 kx
5 kx @deffn Test -links +n
5 kx File has more than @var{n} hard links.
5 kx @end deffn
5 kx
5 kx @deffn Test -links -n
5 kx File has fewer than @var{n} hard links.
5 kx @end deffn
5 kx
5 kx @node Time
5 kx @section Time
5 kx
5 kx Each file has three timestamps, which record the last time that
5 kx certain operations were performed on the file:
5 kx
5 kx @enumerate
5 kx @item
5 kx access (read the file's contents)
5 kx @item
5 kx change the status (modify the file or its attributes)
5 kx @item
5 kx modify (change the file's contents)
5 kx @end enumerate
5 kx
5 kx Some systems also provide a timestamp that indicates when a file was
5 kx @emph{created}. For example, the UFS2 filesystem under NetBSD-3.1
5 kx records the @emph{birth time} of each file. This information is also
5 kx available under other versions of BSD and some versions of Cygwin.
5 kx However, even on systems which support file birth time, files may
5 kx exist for which this information was not recorded (for example, UFS1
5 kx file systems simply do not contain this information).
5 kx
5 kx You can search for files whose timestamps are within a certain age
5 kx range, or compare them to other timestamps.
5 kx
5 kx @menu
5 kx * Age Ranges::
5 kx * Comparing Timestamps::
5 kx @end menu
5 kx
5 kx @node Age Ranges
5 kx @subsection Age Ranges
5 kx
5 kx These tests are mainly useful with ranges (@samp{+@var{n}} and
5 kx @samp{-@var{n}}).
5 kx
5 kx @deffn Test -atime n
5 kx @deffnx Test -ctime n
5 kx @deffnx Test -mtime n
5 kx True if the file was last accessed (or its status changed, or it was
5 kx modified) @var{n}*24 hours ago. The number of 24-hour periods since
5 kx the file's timestamp is always rounded down; therefore 0 means ``less
5 kx than 24 hours ago'', 1 means ``between 24 and 48 hours ago'', and so
5 kx forth. Fractional values are supported but this only really makes
5 kx sense for the case where ranges (@samp{+@var{n}} and @samp{-@var{n}})
5 kx are used.
5 kx @end deffn
5 kx
5 kx @deffn Test -amin n
5 kx @deffnx Test -cmin n
5 kx @deffnx Test -mmin n
5 kx True if the file was last accessed (or its status changed, or it was
5 kx modified) @var{n} minutes ago. These tests provide finer granularity
5 kx of measurement than @samp{-atime} et al., but rounding is done in a
5 kx similar way (again, fractions are supported). For example, to list
5 kx files in @file{/u/bill} that were last read from 2 to 6 minutes ago:
5 kx
5 kx @example
5 kx find /u/bill -amin +2 -amin -6
5 kx @end example
5 kx @end deffn
5 kx
5 kx @deffn Option -daystart
5 kx Measure times from the beginning of today rather than from 24 hours
5 kx ago. So, to list the regular files in your home directory that were
5 kx modified yesterday, do
5 kx
5 kx @example
5 kx find ~/ -daystart -type f -mtime 1
5 kx @end example
5 kx
5 kx The @samp{-daystart} option is unlike most other options in that it
5 kx has an effect on the way that other tests are performed. The affected
5 kx tests are @samp{-amin}, @samp{-cmin}, @samp{-mmin}, @samp{-atime},
5 kx @samp{-ctime} and @samp{-mtime}. The @samp{-daystart} option only
5 kx affects the behaviour of any tests which appear after it on the
5 kx command line.
5 kx @end deffn
5 kx
5 kx @node Comparing Timestamps
5 kx @subsection Comparing Timestamps
5 kx
5 kx @deffn Test -newerXY reference
5 kx Succeeds if timestamp @samp{X} of the file being considered is newer
5 kx than timestamp @samp{Y} of the file @file{reference}. The letters
5 kx @samp{X} and @samp{Y} can be any of the following letters:
5 kx
5 kx @table @samp
5 kx @item a
5 kx Last-access time of @file{reference}
5 kx @item B
5 kx Birth time of @file{reference} (when this is not known, the test cannot succeed)
5 kx @item c
5 kx Last-change time of @file{reference}
5 kx @item m
5 kx Last-modification time of @file{reference}
5 kx @item t
5 kx The @file{reference} argument is interpreted as a literal time, rather
5 kx than the name of a file. @xref{Date input formats}, for a description
5 kx of how the timestamp is understood. Tests of the form @samp{-newerXt}
5 kx are valid but tests of the form @samp{-newertY} are not.
5 kx @end table
5 kx
5 kx For example the test @code{-newerac /tmp/foo} succeeds for all files
5 kx which have been accessed more recently than @file{/tmp/foo} was
5 kx changed. Here @samp{X} is @samp{a} and @samp{Y} is @samp{c}.
5 kx
5 kx Not all files have a known birth time. If @samp{Y} is @samp{b} and
5 kx the birth time of @file{reference} is not available, @code{find} exits
5 kx with an explanatory error message. If @samp{X} is @samp{b} and we do
5 kx not know the birth time the file currently being considered, the test
5 kx simply fails (that is, it behaves like @code{-false} does).
5 kx
5 kx Some operating systems (for example, most implementations of Unix) do
5 kx not support file birth times. Some others, for example NetBSD-3.1,
5 kx do. Even on operating systems which support file birth times, the
5 kx information may not be available for specific files. For example,
5 kx under NetBSD, file birth times are supported on UFS2 file systems, but
5 kx not UFS1 file systems.
5 kx
5 kx @end deffn
5 kx
5 kx
5 kx
5 kx There are two ways to list files in @file{/usr} modified after
5 kx February 1 of the current year. One uses @samp{-newermt}:
5 kx
5 kx @example
5 kx find /usr -newermt "Feb 1"
5 kx @end example
5 kx
5 kx The other way of doing this works on the versions of find before 4.3.3:
5 kx
5 kx @c Idea from Rick Sladkey.
5 kx @example
5 kx touch -t 02010000 /tmp/stamp$$
5 kx find /usr -newer /tmp/stamp$$
5 kx rm -f /tmp/stamp$$
5 kx @end example
5 kx
5 kx @deffn Test -anewer reference
5 kx @deffnx Test -cnewer reference
5 kx @deffnx Test -newer reference
5 kx True if the time of the last access (or status change or data modification)
5 kx of the current file is more recent than that of the last data modification
5 kx of the @var{reference} file.
5 kx As such, @samp{-anewer} is equivalent to @samp{-neweram},
5 kx @samp{-cnewer} to @samp{-newercm}, and @samp{-newer} to @samp{-newermm}.
5 kx
5 kx If @var{reference} is a symbolic link and the @samp{-H} option or the @samp{-L}
5 kx option is in effect, then the time of the last data modification of the file
5 kx it points to is always used.
5 kx
5 kx These tests are affected by @samp{-follow} only if @samp{-follow} comes before
5 kx them on the command line. @xref{Symbolic Links}, for more information on
5 kx @samp{-follow}.
5 kx
5 kx As an example, to list any files modified since
5 kx @file{/bin/sh} was last modified:
5 kx
5 kx @example
5 kx find . -newer /bin/sh
5 kx @end example
5 kx @end deffn
5 kx
5 kx @deffn Test -used n
5 kx True if the file was last accessed @var{n} days after its status was
5 kx last changed. Useful for finding files that are not being used, and
5 kx could perhaps be archived or removed to save disk space.
5 kx @end deffn
5 kx
5 kx @node Size
5 kx @section Size
5 kx
5 kx @deffn Test -size n@r{[}bckwMG@r{]}
5 kx True if the file uses @var{n} units of space, rounding up. The units
5 kx are 512-byte blocks by default, but they can be changed by adding a
5 kx one-character suffix to @var{n}:
5 kx
5 kx @table @code
5 kx @item b
5 kx 512-byte blocks (never 1024)
5 kx @item c
5 kx bytes
5 kx @item w
5 kx 2-byte words
5 kx @item k
5 kx Kibibytes (KiB, units of 1024 bytes)
5 kx @item M
5 kx Mebibytes (MiB, units of 1024 * 1024 = 1048576 bytes)
5 kx @item G
5 kx Gibibytes (GiB, units of 1024 * 1024 * 1024 = 1073741824 bytes)
5 kx @end table
5 kx
5 kx The `b' suffix always considers blocks to be 512 bytes. This is not
5 kx affected by the setting (or non-setting) of the @code{POSIXLY_CORRECT}
5 kx environment variable. This behaviour is different from the behaviour of
5 kx the @samp{-ls} action). If you want to use 1024-byte units, use the
5 kx `k' suffix instead.
5 kx
5 kx The number can be prefixed with a `+' or a `-'. A plus sign indicates
5 kx that the test should succeed if the file uses at least @var{n} units
5 kx of storage (a common use of this test) and a minus sign
5 kx indicates that the test should succeed if the file uses less than
5 kx @var{n} units of storage; i.e., an exact size of @var{n} units does not match.
5 kx Bear in mind that the size is rounded up to
5 kx the next unit. Therefore @samp{-size -1M} is not equivalent to
5 kx @samp{-size -1048576c}. The former only matches empty files, the latter
5 kx matches files from 0 to 1,048,575 bytes. There is no `=' prefix, because
5 kx that's the default anyway.
5 kx
5 kx The size is simply the st_size member of the struct stat populated by
5 kx the lstat (or stat) system call, rounded up as shown above. In other words, it's
5 kx consistent with the result you get for @samp{ls -l}.
5 kx This handling of sparse files differs from the output of the @samp{%k}
5 kx and @samp{%b} format specifiers for the @samp{-printf} predicate.
5 kx
5 kx @end deffn
5 kx
5 kx @deffn Test -empty
5 kx True if the file is empty and is either a regular file or a directory.
5 kx This might help determine good candidates for deletion. This test is
5 kx useful with @samp{-depth} (@pxref{Directories}) and @samp{-delete}
5 kx (@pxref{Single File}).
5 kx @end deffn
5 kx
5 kx @node Type
5 kx @section Type
5 kx
5 kx @deffn Test -type c
5 kx True if the file is of type @var{c}:
5 kx
5 kx @table @code
5 kx @item b
5 kx block (buffered) special
5 kx @item c
5 kx character (unbuffered) special
5 kx @item d
5 kx directory
5 kx @item p
5 kx named pipe (FIFO)
5 kx @item f
5 kx regular file
5 kx @item l
5 kx symbolic link; if @samp{-L} is in effect, this is true only for broken
5 kx symbolic links. If you want to search for symbolic links when
5 kx @samp{-L} is in effect, use @samp{-xtype} instead of @samp{-type}.
5 kx @item s
5 kx socket
5 kx @item D
5 kx door (Solaris)
5 kx @end table
5 kx
5 kx As a GNU extension, multiple file types can be provided as a combined list
5 kx separated by comma @samp{,}. For example, @samp{-type f,d,l} is logically
5 kx interpreted as @samp{( -type f -o -type d -o -type l )}.
5 kx @end deffn
5 kx
5 kx @deffn Test -xtype c
5 kx This test behaves the same as @samp{-type} unless the file is a
5 kx symbolic link. If the file is a symbolic link, the result is as
5 kx follows (in the table below, @samp{X} should be understood to
5 kx represent any letter except @samp{l}):
5 kx
5 kx @table @samp
5 kx @item @samp{-P -xtype l}
5 kx True if the symbolic link is broken
5 kx @item @samp{-P -xtype X}
5 kx True if the (ultimate) target file is of type @samp{X}.
5 kx @item @samp{-L -xtype l}
5 kx Always true
5 kx @item @samp{-L -xtype X}
5 kx False unless the symbolic link is broken
5 kx @end table
5 kx
5 kx In other words, for symbolic links, @samp{-xtype} checks the type of
5 kx the file that @samp{-type} does not check.
5 kx
5 kx The @samp{-H} option also affects the behaviour of @samp{-xtype}.
5 kx When @samp{-H} is in effect, @samp{-xtype} behaves as if @samp{-L} had
5 kx been specified when examining files listed on the command line, and as
5 kx if @samp{-P} had been specified otherwise. If neither @samp{-H} nor
5 kx @samp{-L} was specified, @samp{-xtype} behaves as if @samp{-P} had
5 kx been specified.
5 kx
5 kx @xref{Symbolic Links}, for more information on @samp{-follow} and
5 kx @samp{-L}.
5 kx @end deffn
5 kx
5 kx @node Owner
5 kx @section Owner
5 kx
5 kx @deffn Test -user uname
5 kx @deffnx Test -group gname
5 kx True if the file is owned by user @var{uname} (belongs to group
5 kx @var{gname}). A numeric ID is allowed.
5 kx @end deffn
5 kx
5 kx @deffn Test -uid n
5 kx @deffnx Test -gid n
5 kx True if the file's numeric user ID (group ID) is @var{n}. These tests
5 kx support ranges (@samp{+@var{n}} and @samp{-@var{n}}), unlike
5 kx @samp{-user} and @samp{-group}.
5 kx @end deffn
5 kx
5 kx @deffn Test -nouser
5 kx @deffnx Test -nogroup
5 kx True if no user corresponds to the file's numeric user ID (no group
5 kx corresponds to the numeric group ID). These cases usually mean that
5 kx the files belonged to users who have since been removed from the
5 kx system. You probably should change the ownership of such files to an
5 kx existing user or group, using the @code{chown} or @code{chgrp}
5 kx program.
5 kx @end deffn
5 kx
5 kx @node Mode Bits
5 kx @section File Mode Bits
5 kx
5 kx @xref{File Permissions}, for information on how file mode bits are
5 kx structured and how to specify them.
5 kx
5 kx Four tests determine what users can do with files. These are
5 kx @samp{-readable}, @samp{-writable}, @samp{-executable} and
5 kx @samp{-perm}. The first three tests ask the operating system if the
5 kx current user can perform the relevant operation on a file, while
5 kx @samp{-perm} just examines the file's mode. The file mode may give
5 kx a misleading impression of what the user can actually do, because the
5 kx file may have an access control list, or exist on a read-only
5 kx filesystem, for example. Of these four tests though, only
5 kx @samp{-perm} is specified by the POSIX standard.
5 kx
5 kx The @samp{-readable}, @samp{-writable} and @samp{-executable} tests
5 kx are implemented via the @code{access} system call. This is
5 kx implemented within the operating system itself. If the file being
5 kx considered is on an NFS filesystem, the remote system may allow or
5 kx forbid read or write operations for reasons of which the NFS client
5 kx cannot take account. This includes user-ID mapping, either in the
5 kx general sense or the more restricted sense in which remote superusers
5 kx are treated by the NFS server as if they are the local user
5 kx @samp{nobody} on the NFS server.
5 kx
5 kx None of the tests in this section should be used to verify that a user
5 kx is authorised to perform any operation (on the file being tested or
5 kx any other file) because of the possibility of a race condition. That
5 kx is, the situation may change between the test and an action being
5 kx taken on the basis of the result of that test.
5 kx
5 kx
5 kx @deffn Test -readable
5 kx True if the file can be read by the invoking user.
5 kx @end deffn
5 kx
5 kx @deffn Test -writable
5 kx True if the file can be written by the invoking user. This is an
5 kx in-principle check, and other things may prevent a successful write
5 kx operation; for example, the filesystem might be full.
5 kx @end deffn
5 kx
5 kx @deffn Test -executable
5 kx True if the file can be executed/searched by the invoking user.
5 kx @end deffn
5 kx
5 kx @deffn Test -perm pmode
5 kx
5 kx True if the file's mode bits match @var{pmode}, which can be
5 kx either a symbolic or numeric @var{mode} (@pxref{File Permissions})
5 kx optionally prefixed by @samp{-} or @samp{/}.
5 kx
5 kx Note that @var{pmode} starts with all file mode bits cleared, i.e.,
5 kx does not relate to the process's file creation bit mask (also known
5 kx as @command{umask}).
5 kx
5 kx A @var{pmode} that starts with neither @samp{-} nor @samp{/} matches
5 kx if @var{mode} exactly matches the file mode bits.
5 kx (To avoid confusion with an obsolete GNU extension, @var{mode}
5 kx must not start with a @samp{+} immediately followed by an octal digit.)
5 kx
5 kx A @var{pmode} that starts with @samp{-} matches if
5 kx @emph{all} the file mode bits set in @var{mode} are set for the file;
5 kx bits not set in @var{mode} are ignored.
5 kx
5 kx A @var{pmode} that starts with @samp{/} matches if
5 kx @emph{any} of the file mode bits set in @var{mode} are set for the file;
5 kx bits not set in @var{mode} are ignored.
5 kx This is a GNU extension.
5 kx
5 kx If you don't use the @samp{/} or @samp{-} form with a symbolic mode
5 kx string, you may have to specify a rather complex mode string. For
5 kx example @samp{-perm g=w} will only match files that have mode 0020
5 kx (that is, ones for which group write permission is the only file mode bit
5 kx set). It is more likely that you will want to use the @samp{/} or
5 kx @samp{-} forms, for example @samp{-perm -g=w}, which matches any file
5 kx with group write permission.
5 kx
5 kx
5 kx @table @samp
5 kx @item -perm 664
5 kx Match files that have read and write permission for their owner,
5 kx and group, but that the rest of the world can read but not write to.
5 kx Do not match files that meet these criteria but have other file mode
5 kx bits set (for example if someone can execute/search the file).
5 kx
5 kx @item -perm -664
5 kx Match files that have read and write permission for their owner,
5 kx and group, but that the rest of the world can read but not write to,
5 kx without regard to the presence of any extra file mode bits (for
5 kx example the executable bit). This matches a file with mode
5 kx 0777, for example.
5 kx
5 kx @item -perm /222
5 kx Match files that are writable by somebody (their owner, or
5 kx their group, or anybody else).
5 kx
5 kx @item -perm /022
5 kx Match files that are writable by their group or everyone else - the latter
5 kx often called @dfn{other}. The files don't have to be writable by both the
5 kx group and other to be matched; either will do.
5 kx
5 kx @item -perm /g+w,o+w
5 kx As above.
5 kx
5 kx @item -perm /g=w,o=w
5 kx As above.
5 kx
5 kx @item -perm -022
5 kx Match files that are writable by both their group and everyone else.
5 kx
5 kx @item -perm -g+w,o+w
5 kx As above.
5 kx
5 kx @item -perm -444 -perm /222 ! -perm /111
5 kx Match files that are readable for everybody, have at least one
5 kx write bit set (i.e., somebody can write to them), but that cannot be
5 kx executed/searched by anybody. Note that in some shells the @samp{!} must be
5 kx escaped.
5 kx
5 kx @item -perm -a+r -perm /a+w ! -perm /a+x
5 kx As above.
5 kx
5 kx @end table
5 kx
5 kx @quotation Warning
5 kx If you specify @samp{-perm /000} or @samp{-perm /mode} where the
5 kx symbolic mode @samp{mode} has no bits set, the test matches all files.
5 kx Versions of GNU @code{find} prior to 4.3.3 matched no files in this
5 kx situation.
5 kx @end quotation
5 kx
5 kx @end deffn
5 kx
5 kx @deffn Test -context pattern
5 kx True if file's SELinux context matches the pattern @var{pattern}.
5 kx The pattern uses shell glob matching.
5 kx
5 kx This predicate is supported only on @code{find} versions compiled with
5 kx SELinux support and only when SELinux is enabled.
5 kx @end deffn
5 kx
5 kx @node Contents
5 kx @section Contents
5 kx
5 kx To search for files based on their contents, you can use the
5 kx @code{grep} program. For example, to find out which C source files in
5 kx the current directory contain the string @samp{thing}, you can do:
5 kx
5 kx @example
5 kx grep -l thing *.[ch]
5 kx @end example
5 kx
5 kx If you also want to search for the string in files in subdirectories,
5 kx you can combine @code{grep} with @code{find} and @code{xargs}, like
5 kx this:
5 kx
5 kx @example
5 kx find . -name '*.[ch]' | xargs grep -l thing
5 kx @end example
5 kx
5 kx The @samp{-l} option causes @code{grep} to print only the names of
5 kx files that contain the string, rather than the lines that contain it.
5 kx The string argument (@samp{thing}) is actually a regular expression,
5 kx so it can contain metacharacters. This method can be refined a little
5 kx by using the @samp{-r} option to make @code{xargs} not run @code{grep}
5 kx if @code{find} produces no output, and using the @code{find} action
5 kx @samp{-print0} and the @code{xargs} option @samp{-0} to avoid
5 kx misinterpreting files whose names contain spaces:
5 kx
5 kx @example
5 kx find . -name '*.[ch]' -print0 | xargs -r -0 grep -l thing
5 kx @end example
5 kx
5 kx For a fuller treatment of finding files whose contents match a
5 kx pattern, see the manual page for @code{grep}.
5 kx
5 kx @node Directories
5 kx @section Directories
5 kx
5 kx Here is how to control which directories @code{find} searches, and how
5 kx it searches them. These two options allow you to process a horizontal
5 kx slice of a directory tree.
5 kx
5 kx @deffn Option -maxdepth levels
5 kx Descend at most @var{levels} (a non-negative integer) levels of
5 kx directories below the command line arguments. Using @samp{-maxdepth 0}
5 kx means only apply the tests and actions to the command line arguments.
5 kx
5 kx @example
5 kx $ mkdir -p dir/d1/d2/d3/d4/d5/d6
5 kx
5 kx $ find dir -maxdepth 1
5 kx dir
5 kx dir/d1
5 kx
5 kx $ find dir -mindepth 5
5 kx dir/d1/d2/d3/d4/d5
5 kx dir/d1/d2/d3/d4/d5/d6
5 kx
5 kx $ find dir -mindepth 2 -maxdepth 4
5 kx dir/d1/d2
5 kx dir/d1/d2/d3
5 kx dir/d1/d2/d3/d4
5 kx @end example
5 kx @end deffn
5 kx
5 kx @deffn Option -mindepth levels
5 kx Do not apply any tests or actions at levels less than @var{levels} (a
5 kx non-negative integer). Using @samp{-mindepth 1} means process all files
5 kx except the command line arguments.
5 kx
5 kx See @samp{-maxdepth} for examples.
5 kx @end deffn
5 kx
5 kx @deffn Option -depth
5 kx Process each directory's contents before the directory itself. Doing
5 kx this is a good idea when producing lists of files to archive with
5 kx @code{cpio} or @code{tar}. If a directory does not have write
5 kx permission for its owner, its contents can still be restored from the
5 kx archive since the directory's permissions are restored after its
5 kx contents.
5 kx @end deffn
5 kx
5 kx @deffn Option -d
5 kx This is a deprecated synonym for @samp{-depth}, for compatibility with
5 kx Mac OS X, FreeBSD and OpenBSD. The @samp{-depth} option is a POSIX
5 kx feature, so it is better to use that.
5 kx @end deffn
5 kx
5 kx @deffn Action -prune
5 kx If the file is a directory, do not descend into it. The result is
5 kx true. For example, to skip the directory @file{src/emacs} and all
5 kx files and directories under it, and print the names of the other files
5 kx found:
5 kx
5 kx @example
5 kx find . -wholename './src/emacs' -prune -o -print
5 kx @end example
5 kx
5 kx The above command will not print @file{./src/emacs} among its list of
5 kx results. This however is not due to the effect of the @samp{-prune}
5 kx action (which only prevents further descent, it doesn't make sure we
5 kx ignore that item). Instead, this effect is due to the use of
5 kx @samp{-o}. Since the left hand side of the ``or'' condition has
5 kx succeeded for @file{./src/emacs}, it is not necessary to evaluate the
5 kx right-hand-side (@samp{-print}) at all for this particular file. If
5 kx you wanted to print that directory name you could use either an extra
5 kx @samp{-print} action:
5 kx
5 kx @example
5 kx find . -wholename './src/emacs' -prune -print -o -print
5 kx @end example
5 kx
5 kx or use the comma operator:
5 kx
5 kx @example
5 kx find . -wholename './src/emacs' -prune , -print
5 kx @end example
5 kx
5 kx If the @samp{-depth} option is in effect, the subdirectories will have
5 kx already been visited in any case. Hence @samp{-prune} has no effect
5 kx in this case.
5 kx
5 kx Because @samp{-delete} implies @samp{-depth}, using @samp{-prune} in
5 kx combination with @samp{-delete} may well result in the deletion of
5 kx more files than you intended.
5 kx @end deffn
5 kx
5 kx
5 kx @deffn Action -quit
5 kx Exit immediately (with return value zero if no errors have occurred).
5 kx This is different to @samp{-prune} because @samp{-prune} only applies
5 kx to the contents of pruned directories, while @samp{-quit} simply makes
5 kx @code{find} stop immediately. No child processes will be left
5 kx running. Any command lines which have been built by @samp{-exec
5 kx ... \+} or @samp{-execdir ... \+} are invoked before the program is
5 kx exited. After @samp{-quit} is executed, no more files specified on
5 kx the command line will be processed. For example, @samp{find /tmp/foo
5 kx /tmp/bar -print -quit} will print only @samp{/tmp/foo}. One common
5 kx use of @samp{-quit} is to stop searching the file system once we have
5 kx found what we want. For example, if we want to find just a single
5 kx file we can do this:
5 kx @example
5 kx find / -name needle -print -quit
5 kx @end example
5 kx @noindent
5 kx @end deffn
5 kx
5 kx @deffn Option -noleaf
5 kx Do not optimize by assuming that directories contain 2 fewer
5 kx subdirectories than their hard link count. This option is needed when
5 kx searching filesystems that do not follow the Unix directory-link
5 kx convention, such as CD-ROM or MS-DOS filesystems or AFS volume mount
5 kx points. Each directory on a normal Unix filesystem has at least 2
5 kx hard links: its name and its @file{.} entry. Additionally, its
5 kx subdirectories (if any) each have a @file{..} entry linked to that
5 kx directory. When @code{find} is examining a directory, after it has
5 kx statted 2 fewer subdirectories than the directory's link count, it
5 kx knows that the rest of the entries in the directory are
5 kx non-directories (@dfn{leaf} files in the directory tree). If only the
5 kx files' names need to be examined, there is no need to stat them; this
5 kx gives a significant increase in search speed.
5 kx @end deffn
5 kx
5 kx @deffn Option -ignore_readdir_race
5 kx If a file disappears after its name has been read from a directory but
5 kx before @code{find} gets around to examining the file with @code{stat},
5 kx don't issue an error message. If you don't specify this option, an
5 kx error message will be issued.
5 kx
5 kx Furthermore, @code{find} with the @samp{-ignore_readdir_race} option
5 kx will ignore errors of the @samp{-delete} action in the case the file
5 kx has disappeared since the parent directory was read: it will not output
5 kx an error diagnostic, and the return code of the @samp{-delete} action
5 kx will be true.
5 kx
5 kx This option can be useful in system
5 kx scripts (cron scripts, for example) that examine areas of the
5 kx filesystem that change frequently (mail queues, temporary directories,
5 kx and so forth), because this scenario is common for those sorts of
5 kx directories. Completely silencing error messages from @code{find} is
5 kx undesirable, so this option neatly solves the problem. There is no
5 kx way to search one part of the filesystem with this option on and part
5 kx of it with this option off, though. When this option is turned on and
5 kx find discovers that one of the start-point files specified on the
5 kx command line does not exist, no error message will be issued.
5 kx
5 kx @end deffn
5 kx
5 kx @deffn Option -noignore_readdir_race
5 kx This option reverses the effect of the @samp{-ignore_readdir_race}
5 kx option.
5 kx @end deffn
5 kx
5 kx
5 kx @node Filesystems
5 kx @section Filesystems
5 kx
5 kx A @dfn{filesystem} is a section of a disk, either on the local host or
5 kx mounted from a remote host over a network. Searching network
5 kx filesystems can be slow, so it is common to make @code{find} avoid
5 kx them.
5 kx
5 kx There are two ways to avoid searching certain filesystems. One way is
5 kx to tell @code{find} to only search one filesystem:
5 kx
5 kx @deffn Option -xdev
5 kx @deffnx Option -mount
5 kx Don't descend directories on other filesystems. These options are
5 kx synonyms.
5 kx @end deffn
5 kx
5 kx The other way is to check the type of filesystem each file is on, and
5 kx not descend directories that are on undesirable filesystem types:
5 kx
5 kx @deffn Test -fstype type
5 kx True if the file is on a filesystem of type @var{type}. The valid
5 kx filesystem types vary among different versions of Unix; an incomplete
5 kx list of filesystem types that are accepted on some version of Unix or
5 kx another is:
5 kx @example
5 kx autofs ext3 ext4 fuse.sshfs nfs proc sshfs sysfs ufs tmpfs xfs
5 kx @end example
5 kx You can use @samp{-printf} with the @samp{%F} directive to see the
5 kx types of your filesystems. The @samp{%D} directive shows the device
5 kx number. @xref{Print File Information}. @samp{-fstype} is usually
5 kx used with @samp{-prune} to avoid searching remote filesystems
5 kx (@pxref{Directories}).
5 kx @end deffn
5 kx
5 kx @node Combining Primaries With Operators
5 kx @section Combining Primaries With Operators
5 kx
5 kx Operators build a complex expression from tests and actions.
5 kx The operators are, in order of decreasing precedence:
5 kx
5 kx @table @code
5 kx @item @asis{( @var{expr} )}
5 kx @findex ()
5 kx Force precedence. True if @var{expr} is true.
5 kx
5 kx @item @asis{! @var{expr}}
5 kx @itemx @asis{-not @var{expr}}
5 kx @findex !
5 kx @findex -not
5 kx True if @var{expr} is false. In some shells, it is necessary to
5 kx protect the @samp{!} from shell interpretation by quoting it.
5 kx
5 kx @item @asis{@var{expr1 expr2}}
5 kx @itemx @asis{@var{expr1} -a @var{expr2}}
5 kx @itemx @asis{@var{expr1} -and @var{expr2}}
5 kx @findex -and
5 kx @findex -a
5 kx And; @var{expr2} is not evaluated if @var{expr1} is false.
5 kx
5 kx @item @asis{@var{expr1} -o @var{expr2}}
5 kx @itemx @asis{@var{expr1} -or @var{expr2}}
5 kx @findex -or
5 kx @findex -o
5 kx Or; @var{expr2} is not evaluated if @var{expr1} is true.
5 kx
5 kx @item @asis{@var{expr1} , @var{expr2}}
5 kx @findex ,
5 kx List; both @var{expr1} and @var{expr2} are always evaluated. True if
5 kx @var{expr2} is true. The value of @var{expr1} is discarded. This
5 kx operator lets you do multiple independent operations on one traversal,
5 kx without depending on whether other operations succeeded. The two
5 kx operations @var{expr1} and @var{expr2} are not always fully
5 kx independent, since @var{expr1} might have side effects like touching
5 kx or deleting files, or it might use @samp{-prune} which would also
5 kx affect @var{expr2}.
5 kx @end table
5 kx
5 kx @code{find} searches the directory tree rooted at each file name by
5 kx evaluating the expression from left to right, according to the rules
5 kx of precedence, until the outcome is known (the left hand side is false
5 kx for @samp{-and}, true for @samp{-or}), at which point @code{find}
5 kx moves on to the next file name.
5 kx
5 kx There are two other tests that can be useful in complex expressions:
5 kx
5 kx @deffn Test -true
5 kx Always true.
5 kx @end deffn
5 kx
5 kx @deffn Test -false
5 kx Always false.
5 kx @end deffn
5 kx
5 kx @node Actions
5 kx @chapter Actions
5 kx
5 kx There are several ways you can print information about the files that
5 kx match the criteria you gave in the @code{find} expression. You can
5 kx print the information either to the standard output or to a file that
5 kx you name. You can also execute commands that have the file names as
5 kx arguments. You can use those commands as further filters to select
5 kx files.
5 kx
5 kx @menu
5 kx * Print File Name::
5 kx * Print File Information::
5 kx * Run Commands::
5 kx * Delete Files::
5 kx * Adding Tests::
5 kx @end menu
5 kx
5 kx @node Print File Name
5 kx @section Print File Name
5 kx
5 kx @deffn Action -print
5 kx True; print the entire file name on the standard output, followed by a
5 kx newline. If there is the faintest possibility that one of the files
5 kx for which you are searching might contain a newline, you should use
5 kx @samp{-print0} instead.
5 kx @end deffn
5 kx
5 kx @deffn Action -fprint file
5 kx True; print the entire file name into file @var{file}, followed by a
5 kx newline. If @var{file} does not exist when @code{find} is run, it is
5 kx created; if it does exist, it is truncated to 0 bytes. The named
5 kx output file is always created, even if no output is sent to it. The
5 kx file names @file{/dev/stdout} and @file{/dev/stderr} are handled
5 kx specially; they refer to the standard output and standard error
5 kx output, respectively.
5 kx
5 kx If there is the faintest possibility that one of the files for which
5 kx you are searching might contain a newline, you should use
5 kx @samp{-fprint0} instead.
5 kx @end deffn
5 kx
5 kx
5 kx @c @deffn Option -show-control-chars how
5 kx @c This option affects how some of @code{find}'s actions treat
5 kx @c unprintable characters in file names. If @samp{how} is
5 kx @c @samp{literal}, any subsequent actions (i.e., actions further on in the
5 kx @c command line) print file names as-is.
5 kx @c
5 kx @c If this option is not specified, it currently defaults to @samp{safe}.
5 kx @c If @samp{how} is @samp{safe}, C-like backslash escapes are used to
5 kx @c indicate the non-printable characters for @samp{-ls} and @samp{-fls}.
5 kx @c On the other hand, @samp{-print}, @samp{-fprint}, @samp{-fprintf} and
5 kx @c @code{-printf} all quote unprintable characters if the data is going
5 kx @c to a tty, and otherwise the data is emitted literally.
5 kx @c
5 kx @c @table @code
5 kx @c @item -ls
5 kx @c Escaped if @samp{how} is @samp{safe}
5 kx @c @item -fls
5 kx @c Escaped if @samp{how} is @samp{safe}
5 kx @c @item -print
5 kx @c Always quoted if stdout is a tty,
5 kx @c @samp{-show-control-chars} is ignored
5 kx @c @item -print0
5 kx @c Always literal, never escaped
5 kx @c @item -fprint
5 kx @c Always quoted if the destination is a tty;
5 kx @c @samp{-show-control-chars} is ignored
5 kx @c @item -fprint0
5 kx @c Always literal, never escaped
5 kx @c @item -fprintf
5 kx @c If the destination is a tty, the @samp{%f},
5 kx @c @samp{%F}, @samp{%h}, @samp{%l}, @samp{%p},
5 kx @c and @samp{%P} directives produce quoted
5 kx @c strings if stdout is a tty and are treated
5 kx @c literally otherwise.
5 kx @c @item -printf
5 kx @c As for @code{-fprintf}.
5 kx @c @end table
5 kx @c @end deffn
5 kx
5 kx
5 kx @node Print File Information
5 kx @section Print File Information
5 kx
5 kx @deffn Action -ls
5 kx True; list the current file in @samp{ls -dils} format on the standard
5 kx output. The output looks like this:
5 kx
5 kx @smallexample
5 kx 204744 17 -rw-r--r-- 1 djm staff 17337 Nov 2 1992 ./lwall-quotes
5 kx @end smallexample
5 kx
5 kx The fields are:
5 kx
5 kx @enumerate
5 kx @item
5 kx The inode number of the file. @xref{Hard Links}, for how to find
5 kx files based on their inode number.
5 kx
5 kx @item
5 kx the number of blocks in the file. The block counts are of 1K blocks,
5 kx unless the environment variable @code{POSIXLY_CORRECT} is set, in
5 kx which case 512-byte blocks are used. @xref{Size}, for how to find
5 kx files based on their size.
5 kx
5 kx @item
5 kx The file's type and file mode bits. The type is shown as a dash for a
5 kx regular file; for other file types, a letter like for @samp{-type} is
5 kx used (@pxref{Type}). The file mode bits are read, write, and execute/search for
5 kx the file's owner, its group, and other users, respectively; a dash
5 kx means the permission is not granted. @xref{File Permissions}, for
5 kx more details about file permissions. @xref{Mode Bits}, for how to
5 kx find files based on their file mode bits.
5 kx
5 kx @item
5 kx The number of hard links to the file.
5 kx
5 kx @item
5 kx The user who owns the file.
5 kx
5 kx @item
5 kx The file's group.
5 kx
5 kx @item
5 kx The file's size in bytes.
5 kx
5 kx @item
5 kx The date the file was last modified.
5 kx
5 kx @item
5 kx The file's name. @samp{-ls} quotes non-printable characters in the
5 kx file names using C-like backslash escapes. This may change soon, as
5 kx the treatment of unprintable characters is harmonised for @samp{-ls},
5 kx @samp{-fls}, @samp{-print}, @samp{-fprint}, @samp{-printf} and
5 kx @samp{-fprintf}.
5 kx @end enumerate
5 kx @end deffn
5 kx
5 kx @deffn Action -fls file
5 kx True; like @samp{-ls} but write to @var{file} like @samp{-fprint}
5 kx (@pxref{Print File Name}). The named output file is always created,
5 kx even if no output is sent to it.
5 kx @end deffn
5 kx
5 kx @deffn Action -printf format
5 kx True; print @var{format} on the standard output, interpreting @samp{\}
5 kx escapes and @samp{%} directives (more details in the following
5 kx sections).
5 kx
5 kx Field widths and precisions can be specified as with the @code{printf} C
5 kx function. Format flags (like @samp{#} for example) may not work as you
5 kx expect because many of the fields, even numeric ones, are printed with
5 kx %s. Numeric flags which are affected in this way include @samp{G},
5 kx @samp{U}, @samp{b}, @samp{D}, @samp{k} and @samp{n}. This difference in
5 kx behaviour means though that the format flag @samp{-} will work; it
5 kx forces left-alignment of the field. Unlike @samp{-print},
5 kx @samp{-printf} does not add a newline at the end of the string. If you
5 kx want a newline at the end of the string, add a @samp{\n}.
5 kx
5 kx As an example, an approximate equivalent of @samp{-ls} with
5 kx null-terminated filenames can be achieved with this @code{-printf}
5 kx format:
5 kx
5 kx @example
5 kx find -printf "%i %4k %M %3n %-8u %-8g %8s %T+ %p\n->%l\0" | cat
5 kx @end example
5 kx
5 kx A practical reason for doing this would be to get literal filenames in
5 kx the output, instead of @samp{-ls}'s backslash-escaped names. (Using
5 kx @code{cat} here prevents this happening for the @samp{%p} format
5 kx specifier; @pxref{Unusual Characters in File Names}). This format also
5 kx outputs a uniform timestamp format.
5 kx
5 kx As for symbolic links, the format above outputs the target of the symbolic link
5 kx on a second line, following @samp{\n->}. There is nothing following the arrow
5 kx for file types other than symbolic links.
5 kx Another approach, for complete consistency, would be to @code{-fprintf} the
5 kx symbolic links into a separate file, so they too can be null-terminated.
5 kx @end deffn
5 kx
5 kx @deffn Action -fprintf file format
5 kx True; like @samp{-printf} but write to @var{file} like @samp{-fprint}
5 kx (@pxref{Print File Name}). The output file is always created, even if
5 kx no output is ever sent to it.
5 kx @end deffn
5 kx
5 kx @menu
5 kx * Escapes::
5 kx * Format Directives::
5 kx * Time Formats::
5 kx * Formatting Flags::
5 kx @end menu
5 kx
5 kx @node Escapes
5 kx @subsection Escapes
5 kx
5 kx The escapes that @samp{-printf} and @samp{-fprintf} recognise are:
5 kx
5 kx @table @code
5 kx @item \a
5 kx Alarm bell.
5 kx @item \b
5 kx Backspace.
5 kx @item \c
5 kx Stop printing from this format immediately and flush the output.
5 kx @item \f
5 kx Form feed.
5 kx @item \n
5 kx Newline.
5 kx @item \r
5 kx Carriage return.
5 kx @item \t
5 kx Horizontal tab.
5 kx @item \v
5 kx Vertical tab.
5 kx @item \\
5 kx A literal backslash (@samp{\}).
5 kx @item \0
5 kx ASCII NUL.
5 kx @item \NNN
5 kx The character whose ASCII code is NNN (octal).
5 kx @end table
5 kx
5 kx A @samp{\} character followed by any other character is treated as an
5 kx ordinary character, so they both are printed, and a warning message is
5 kx printed to the standard error output (because it was probably a typo).
5 kx
5 kx @node Format Directives
5 kx @subsection Format Directives
5 kx
5 kx @samp{-printf} and @samp{-fprintf} support the following format
5 kx directives to print information about the file being processed. The C
5 kx @code{printf} function, field width and precision specifiers are
5 kx supported, as applied to string (%s) types. That is, you can specify
5 kx "minimum field width"."maximum field width" for each directive.
5 kx Format flags (like @samp{#} for example) may not work as you expect
5 kx because many of the fields, even numeric ones, are printed with %s.
5 kx The format flag @samp{-} does work; it forces left-alignment of the
5 kx field.
5 kx
5 kx @samp{%%} is a literal percent sign. @xref{Reserved and Unknown
5 kx Directives}, for a description of how format directives not mentioned
5 kx below are handled.
5 kx
5 kx A @samp{%} at the end of the format argument causes undefined
5 kx behaviour since there is no following character. In some locales, it
5 kx may hide your door keys, while in others it may remove the final page
5 kx from the novel you are reading.
5 kx
5 kx @menu
5 kx * Name Directives::
5 kx * Ownership Directives::
5 kx * Size Directives::
5 kx * Location Directives::
5 kx * Time Directives::
5 kx * Other Directives::
5 kx * Reserved and Unknown Directives::
5 kx @end menu
5 kx
5 kx @node Name Directives
5 kx @subsubsection Name Directives
5 kx
5 kx @table @code
5 kx @item %p
5 kx @c supports %-X.Yp
5 kx File's name (not the absolute path name, but the name of the file as
5 kx it was encountered by @code{find} - that is, as a relative path from
5 kx one of the starting points).
5 kx @item %f
5 kx File's name with any leading directories removed (only the last
5 kx element). That is, the basename of the file.
5 kx @c supports %-X.Yf
5 kx @item %h
5 kx Leading directories of file's name (all but the last element and the
5 kx slash before it). That is, the dirname of the file. If the file's
5 kx name contains no slashes (for example because it was named on the
5 kx command line and is in the current working directory), then ``%h''
5 kx expands to ``.''. This prevents ``%h/%f'' expanding to ``/foo'',
5 kx which would be surprising and probably not desirable.
5 kx @c supports %-X.Yh
5 kx @item %P
5 kx File's name with the name of the command line argument under which
5 kx it was found removed from the beginning.
5 kx @c supports %-X.YP
5 kx @item %H
5 kx Command line argument under which file was found.
5 kx @c supports %-X.YH
5 kx @end table
5 kx
5 kx For some corner-cases, the interpretation of the @samp{%f} and
5 kx @samp{%h} format directives is not obvious. Here is an example
5 kx including some output:
5 kx
5 kx @example
5 kx $ find \
5 kx . .. / /tmp /tmp/TRACE compile compile/64/tests/find \
5 kx -maxdepth 0 -printf '%p: [%h][%f]\n'
5 kx .: [.][.]
5 kx ..: [.][..]
5 kx /: [][/]
5 kx /tmp: [][tmp]
5 kx /tmp/TRACE: [/tmp][TRACE]
5 kx compile: [.][compile]
5 kx compile/64/tests/find: [compile/64/tests][find]
5 kx @end example
5 kx
5 kx @node Ownership Directives
5 kx @subsubsection Ownership Directives
5 kx
5 kx @table @code
5 kx @item %g
5 kx @c supports %-X.Yg
5 kx File's group name, or numeric group ID if the group has no name.
5 kx @item %G
5 kx @c supports %-X.Yg
5 kx @c TODO: Needs to support # flag and 0 flag
5 kx File's numeric group ID.
5 kx @item %u
5 kx @c supports %-X.Yu
5 kx File's user name, or numeric user ID if the user has no name.
5 kx @item %U
5 kx @c supports %-X.Yu
5 kx @c TODO: Needs to support # flag
5 kx File's numeric user ID.
5 kx @item %m
5 kx @c full support, including # and 0.
5 kx File's mode bits (in octal). If you always want to have a leading
5 kx zero on the number, use the '#' format flag, for example '%#m'.
5 kx
5 kx The file mode bit numbers used are the traditional Unix
5 kx numbers, which will be as expected on most systems, but if your
5 kx system's file mode bit layout differs from the traditional Unix
5 kx semantics, you will see a difference between the mode as printed by
5 kx @samp{%m} and the mode as it appears in @code{struct stat}.
5 kx
5 kx @item %M
5 kx File's type and mode bits (in symbolic form, as for @code{ls}). This
5 kx directive is supported in findutils 4.2.5 and later.
5 kx @end table
5 kx
5 kx @node Size Directives
5 kx @subsubsection Size Directives
5 kx
5 kx @table @code
5 kx @item %k
5 kx The amount of disk space used for this file in 1K blocks. Since disk
5 kx space is allocated in multiples of the filesystem block size this is
5 kx usually greater than %s/1024, but it can also be smaller if the file
5 kx is a sparse file (that is, it has ``holes'').
5 kx @item %b
5 kx The amount of disk space used for this file in 512-byte blocks. Since
5 kx disk space is allocated in multiples of the filesystem block size this
5 kx is usually greater than %s/512, but it can also be smaller if the
5 kx file is a sparse file (that is, it has ``holes'').
5 kx @item %s
5 kx File's size in bytes.
5 kx @item %S
5 kx File's sparseness. This is calculated as @code{(BLOCKSIZE*st_blocks /
5 kx st_size)}. The exact value you will get for an ordinary file of a
5 kx certain length is system-dependent. However, normally sparse files
5 kx will have values less than 1.0, and files which use indirect blocks
5 kx and have few holes may have a value which is greater than 1.0. The
5 kx value used for BLOCKSIZE is system-dependent, but is usually 512
5 kx bytes. If the file size is zero, the value printed is undefined. On
5 kx systems which lack support for st_blocks, a file's sparseness is
5 kx assumed to be 1.0.
5 kx @end table
5 kx
5 kx @node Location Directives
5 kx @subsubsection Location Directives
5 kx
5 kx @table @code
5 kx @item %d
5 kx File's depth in the directory tree (depth below a file named on the
5 kx command line, not depth below the root directory). Files named on the
5 kx command line have a depth of 0. Subdirectories immediately below them
5 kx have a depth of 1, and so on.
5 kx @item %D
5 kx The device number on which the file exists (the @code{st_dev} field of
5 kx @code{struct stat}), in decimal.
5 kx @item %F
5 kx Type of the filesystem the file is on; this value can be used for
5 kx @samp{-fstype} (@pxref{Directories}).
5 kx @item %l
5 kx Object of symbolic link (empty string if file is not a symbolic link).
5 kx @item %i
5 kx File's inode number (in decimal).
5 kx @item %n
5 kx Number of hard links to file.
5 kx @item %y
5 kx Type of the file as used with @samp{-type}. If the file is a symbolic
5 kx link, @samp{l} will be printed.
5 kx @item %Y
5 kx Type of the file as used with @samp{-type}. If the file is a symbolic
5 kx link, it is dereferenced. If the file is a broken symbolic link,
5 kx @samp{N} is printed.
5 kx When determining the type of the target of a symbolic link, and a loop is
5 kx encountered, then @samp{L} is printed (e.g. for a symbolic link to itself);
5 kx @samp{?} is printed for any other error (like e.g. @samp{permission denied}).
5 kx
5 kx @end table
5 kx
5 kx @node Time Directives
5 kx @subsubsection Time Directives
5 kx
5 kx Some of these directives use the C @code{ctime} function. Its output
5 kx depends on the current locale, but it typically looks like
5 kx
5 kx @example
5 kx Wed Nov 2 00:42:36 1994
5 kx @end example
5 kx
5 kx @table @code
5 kx @item %a
5 kx File's last access time in the format returned by the C @code{ctime}
5 kx function.
5 kx @item %A@var{k}
5 kx File's last access time in the format specified by @var{k}
5 kx (@pxref{Time Formats}).
5 kx @item %c
5 kx File's last status change time in the format returned by the C
5 kx @code{ctime} function.
5 kx @item %C@var{k}
5 kx File's last status change time in the format specified by @var{k}
5 kx (@pxref{Time Formats}).
5 kx @item %t
5 kx File's last modification time in the format returned by the C
5 kx @code{ctime} function.
5 kx @item %T@var{k}
5 kx File's last modification time in the format specified by @var{k}
5 kx (@pxref{Time Formats}).
5 kx @end table
5 kx
5 kx @node Other Directives
5 kx @subsubsection Other Directives
5 kx
5 kx @table @code
5 kx @item %Z
5 kx File's SELinux context, or empty string if the file has no SELinux context.
5 kx @end table
5 kx
5 kx @node Reserved and Unknown Directives
5 kx @subsubsection Reserved and Unknown Directives
5 kx
5 kx The @samp{%(}, @samp{%@{} and @samp{%[} format directives, with or
5 kx without field with and precision specifications, are reserved for
5 kx future use. Don't use them and don't rely on current experiment to
5 kx predict future behaviour. To print @samp{(}, simply use @samp{(}
5 kx rather than @samp{%(}. Likewise for @samp{@{} and @samp{[}.
5 kx
5 kx Similarly, a @samp{%} character followed by any other unrecognised
5 kx character (i.e., not a known directive or @code{printf} field width
5 kx and precision specifier), is discarded (but the unrecognised character
5 kx is printed), and a warning message is printed to the standard error
5 kx output (because it was probably a typo). Don't rely on this
5 kx behaviour, because other directives may be added in the future.
5 kx
5 kx
5 kx @node Time Formats
5 kx @subsection Time Formats
5 kx
5 kx Below is an incomplete list of formats for the directives @samp{%A}, @samp{%C},
5 kx and @samp{%T}, which print the file's timestamps.
5 kx Please refer to the documentation of @code{strftime} for the full list.
5 kx Some of these formats might not be available on all systems, due to differences
5 kx in the implementation of the C @code{strftime} function.
5 kx
5 kx @menu
5 kx * Time Components::
5 kx * Date Components::
5 kx * Combined Time Formats::
5 kx @end menu
5 kx
5 kx @node Time Components
5 kx @subsubsection Time Components
5 kx
5 kx The following format directives print single components of the time.
5 kx
5 kx @table @code
5 kx @item H
5 kx hour (00..23)
5 kx @item I
5 kx hour (01..12)
5 kx @item k
5 kx hour ( 0..23)
5 kx @item l
5 kx hour ( 1..12)
5 kx @item p
5 kx locale's AM or PM
5 kx @item Z
5 kx time zone (e.g., EDT), or nothing if no time zone is determinable
5 kx @item M
5 kx minute (00..59)
5 kx @item S
5 kx second (00..61). There is a fractional part.
5 kx @item @@
5 kx seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
5 kx @end table
5 kx
5 kx The fractional part of the seconds field is of indeterminate length
5 kx and precision. That is, the length of the fractional part of the
5 kx seconds field will in general vary between findutils releases and
5 kx between systems. This means that it is unwise to assume that field
5 kx has any specific length. The length of this field is not usually a
5 kx guide to the precision of timestamps in the underlying file system.
5 kx
5 kx
5 kx
5 kx @node Date Components
5 kx @subsubsection Date Components
5 kx
5 kx The following format directives print single components of the date.
5 kx
5 kx @table @code
5 kx @item a
5 kx locale's abbreviated weekday name (Sun..Sat)
5 kx @item A
5 kx locale's full weekday name, variable length (Sunday..Saturday)
5 kx @item b
5 kx @itemx h
5 kx locale's abbreviated month name (Jan..Dec)
5 kx @item B
5 kx locale's full month name, variable length (January..December)
5 kx @item m
5 kx month (01..12)
5 kx @item d
5 kx day of month (01..31)
5 kx @item w
5 kx day of week (0..6)
5 kx @item j
5 kx day of year (001..366)
5 kx @item U
5 kx week number of year with Sunday as first day of week (00..53)
5 kx @item W
5 kx week number of year with Monday as first day of week (00..53)
5 kx @item Y
5 kx year (1970@dots{})
5 kx @item y
5 kx last two digits of year (00..99)
5 kx @end table
5 kx
5 kx @node Combined Time Formats
5 kx @subsubsection Combined Time Formats
5 kx
5 kx The following format directives print combinations of time and date
5 kx components.
5 kx
5 kx @table @code
5 kx @item r
5 kx time, 12-hour (hh:mm:ss [AP]M)
5 kx @item T
5 kx time, 24-hour (hh:mm:ss.xxxxxxxxxx)
5 kx @item X
5 kx locale's time representation (H:M:S). The seconds field includes a
5 kx fractional part.
5 kx @item c
5 kx locale's date and time in ctime format (Sat Nov 04 12:02:33 EST
5 kx 1989). This format does not include any fractional part in the
5 kx seconds field.
5 kx @item D
5 kx date (mm/dd/yy)
5 kx @item F
5 kx date (yyyy-mm-dd)
5 kx @item x
5 kx locale's date representation (mm/dd/yy)
5 kx @item +
5 kx Date and time, separated by '+', for example
5 kx `2004-04-28+22:22:05.0000000000'.
5 kx The time is given in the current timezone (which may be affected by
5 kx setting the TZ environment variable). This is a GNU extension. The
5 kx seconds field includes a fractional part.
5 kx @end table
5 kx
5 kx @node Formatting Flags
5 kx @subsection Formatting Flags
5 kx
5 kx The @samp{%m} and @samp{%d} directives support the @samp{#}, @samp{0}
5 kx and @samp{+} flags, but the other directives do not, even if they
5 kx print numbers. Numeric directives that do not support these flags
5 kx include
5 kx
5 kx @samp{G},
5 kx @samp{U},
5 kx @samp{b},
5 kx @samp{D},
5 kx @samp{k} and
5 kx @samp{n}.
5 kx
5 kx All fields support the format flag @samp{-}, which makes fields
5 kx left-aligned. That is, if the field width is greater than the actual
5 kx contents of the field, the requisite number of spaces are printed
5 kx after the field content instead of before it.
5 kx
5 kx @node Run Commands
5 kx @section Run Commands
5 kx
5 kx You can use the list of file names created by @code{find} or
5 kx @code{locate} as arguments to other commands. In this way you can
5 kx perform arbitrary actions on the files.
5 kx
5 kx @menu
5 kx * Single File::
5 kx * Multiple Files::
5 kx * Querying::
5 kx @end menu
5 kx
5 kx @node Single File
5 kx @subsection Single File
5 kx
5 kx Here is how to run a command on one file at a time.
5 kx
5 kx @deffn Action -execdir command ;
5 kx Execute @var{command}; true if @var{command} returns zero. @code{find}
5 kx takes all arguments after @samp{-execdir} to be part of the command until
5 kx an argument consisting of @samp{;} is reached. It replaces the string
5 kx @samp{@{@}} by the current file name being processed everywhere it
5 kx occurs in the command. Both of these constructions need to be escaped
5 kx (with a @samp{\}) or quoted to protect them from expansion by the
5 kx shell. The command is executed in the directory which @code{find}
5 kx was searching at the time the action was executed (that is, @{@} will
5 kx expand to a file in the local directory).
5 kx
5 kx For example, to compare each C header file in or below the current
5 kx directory with the file @file{/tmp/master}:
5 kx
5 kx @example
5 kx find . -name '*.h' -execdir diff -u '@{@}' /tmp/master ';'
5 kx @end example
5 kx @end deffn
5 kx
5 kx If you use @samp{-execdir}, you must ensure that the @samp{$PATH}
5 kx variable contains only absolute directory names. Having an empty
5 kx element in @samp{$PATH} or explicitly including @samp{.} (or any other
5 kx non-absolute name) is insecure. GNU find will refuse to run if you
5 kx use @samp{-execdir} and it thinks your @samp{$PATH} setting is
5 kx insecure. For example:
5 kx
5 kx @table @samp
5 kx @item /bin:/usr/bin:
5 kx Insecure; empty path element (at the end)
5 kx @item :/bin:/usr/bin:/usr/local/bin
5 kx Insecure; empty path element (at the start)
5 kx @item /bin:/usr/bin::/usr/local/bin
5 kx Insecure; empty path element (two colons in a row)
5 kx @item /bin:/usr/bin:.:/usr/local/bin
5 kx Insecure; @samp{.} is a path element (@file{.} is not an absolute file name)
5 kx @item /bin:/usr/bin:sbin:/usr/local/bin
5 kx Insecure; @samp{sbin} is not an absolute file name
5 kx @item /bin:/usr/bin:/sbin:/usr/local/bin
5 kx Secure (if you control the contents of those directories and any access to them)
5 kx @end table
5 kx
5 kx Another similar option, @samp{-exec} is supported, but is less secure.
5 kx @xref{Security Considerations}, for a discussion of the security
5 kx problems surrounding @samp{-exec}.
5 kx
5 kx
5 kx @deffn Action -exec command ;
5 kx This insecure variant of the @samp{-execdir} action is specified by
5 kx POSIX. Like @samp{-execdir command ;} it is true if zero is
5 kx returned by @var{command}. The main difference is that the command is
5 kx executed in the directory from which @code{find} was invoked, meaning
5 kx that @samp{@{@}} is expanded to a relative path starting with the name
5 kx of one of the starting directories, rather than just the basename of
5 kx the matched file.
5 kx
5 kx While some implementations of @code{find} replace the @samp{@{@}} only
5 kx where it appears on its own in an argument, GNU @code{find} replaces
5 kx @samp{@{@}} wherever it appears.
5 kx @end deffn
5 kx
5 kx
5 kx @node Multiple Files
5 kx @subsection Multiple Files
5 kx
5 kx Sometimes you need to process files one at a time. But usually this
5 kx is not necessary, and, it is faster to run a command on as many files
5 kx as possible at a time, rather than once per file. Doing this saves on
5 kx the time it takes to start up the command each time.
5 kx
5 kx The @samp{-execdir} and @samp{-exec} actions have variants that build
5 kx command lines containing as many matched files as possible.
5 kx
5 kx @deffn Action -execdir command @{@} +
5 kx This works as for @samp{-execdir command ;}, except that the result is
5 kx always true, and the @samp{@{@}} at the end of the command is expanded
5 kx to a list of names of matching files. This expansion is done in such
5 kx a way as to avoid exceeding the maximum command line length available
5 kx on the system. Only one @samp{@{@}} is allowed within the command,
5 kx and it must appear at the end, immediately before the @samp{+}. A
5 kx @samp{+} appearing in any position other than immediately after
5 kx @samp{@{@}} is not considered to be special (that is, it does not
5 kx terminate the command).
5 kx @end deffn
5 kx
5 kx
5 kx @deffn Action -exec command @{@} +
5 kx This insecure variant of the @samp{-execdir} action is specified by
5 kx POSIX. The main difference is that the command is executed in the
5 kx directory from which @code{find} was invoked, meaning that @samp{@{@}}
5 kx is expanded to a relative path starting with the name of one of the
5 kx starting directories, rather than just the basename of the matched
5 kx file. The result is always true.
5 kx @end deffn
5 kx
5 kx Before @code{find} exits, any partially-built command lines are
5 kx executed. This happens even if the exit was caused by the
5 kx @samp{-quit} action. However, some types of error (for example not
5 kx being able to invoke @code{stat()} on the current directory) can cause
5 kx an immediate fatal exit. In this situation, any partially-built
5 kx command lines will not be invoked (this prevents possible infinite
5 kx loops).
5 kx
5 kx At first sight, it looks like the list of filenames to be processed
5 kx can only be at the end of the command line, and that this might be a
5 kx problem for some commands (@code{cp} and @code{rsync} for example).
5 kx
5 kx However, there is a slightly obscure but powerful workaround for this
5 kx problem which takes advantage of the behaviour of @code{sh -c}:
5 kx
5 kx @example
5 kx find startpoint -tests @dots{} -exec sh -c 'scp "$@@" remote:/dest' sh @{@} +
5 kx @end example
5 kx
5 kx In the example above, the filenames we want to work on need to occur
5 kx on the @code{scp} command line before the name of the destination. We
5 kx use the shell to invoke the command @code{scp "$@@" remote:/dest} and
5 kx the shell expands @code{"$@@"} to the list of filenames we want to
5 kx process.
5 kx
5 kx Another, but less secure, way to run a command on more than one file
5 kx at once, is to use the @code{xargs} command, which is invoked like
5 kx this:
5 kx
5 kx @example
5 kx xargs @r{[}@var{option}@dots{}@r{]} @r{[}@var{command} @r{[}@var{initial-arguments}@r{]}@r{]}
5 kx @end example
5 kx
5 kx @code{xargs} normally reads arguments from the standard input. These
5 kx arguments are delimited by blanks (which can be protected with double
5 kx or single quotes or a backslash) or newlines. It executes the
5 kx @var{command} (the default is @file{echo}) one or more times with any
5 kx @var{initial-arguments} followed by arguments read from standard
5 kx input. Blank lines on the standard input are ignored. If the
5 kx @samp{-L} option is in use, trailing blanks indicate that @code{xargs}
5 kx should consider the following line to be part of this one.
5 kx
5 kx Instead of blank-delimited names, it is safer to use @samp{find
5 kx -print0} or @samp{find -fprint0} and process the output by giving the
5 kx @samp{-0} or @samp{--null} option to GNU @code{xargs}, GNU @code{tar},
5 kx GNU @code{cpio}, or @code{perl}. The @code{locate} command also has a
5 kx @samp{-0} or @samp{--null} option which does the same thing.
5 kx
5 kx You can use shell command substitution (backquotes) to process a list
5 kx of arguments, like this:
5 kx
5 kx @example
5 kx grep -l sprintf `find $HOME -name '*.c' -print`
5 kx @end example
5 kx
5 kx However, that method produces an error if the length of the @samp{.c}
5 kx file names exceeds the operating system's command line length limit.
5 kx @code{xargs} avoids that problem by running the command as many times
5 kx as necessary without exceeding the limit:
5 kx
5 kx @example
5 kx find $HOME -name '*.c' -print | xargs grep -l sprintf
5 kx @end example
5 kx
5 kx However, if the command needs to have its standard input be a terminal
5 kx (@code{less}, for example), you have to use the shell command
5 kx substitution method or use either the @samp{--arg-file} option or the
5 kx @samp{--open-tty} option of @code{xargs}.
5 kx
5 kx The @code{xargs} command will process all its input, building command
5 kx lines and executing them, unless one of the commands exits with a
5 kx status of 255 (this will cause xargs to issue an error message and
5 kx stop) or it reads a line contains the end of file string specified
5 kx with the @samp{--eof} option.
5 kx
5 kx @menu
5 kx * Unsafe File Name Handling::
5 kx * Safe File Name Handling::
5 kx * Unusual Characters in File Names::
5 kx * Limiting Command Size::
5 kx * Controlling Parallelism::
5 kx * Interspersing File Names::
5 kx @end menu
5 kx
5 kx @node Unsafe File Name Handling
5 kx @subsubsection Unsafe File Name Handling
5 kx
5 kx Because file names can contain quotes, backslashes, blank characters,
5 kx and even newlines, it is not safe to process them using @code{xargs}
5 kx in its default mode of operation. But since most files' names do not
5 kx contain blanks, this problem occurs only infrequently. If you are
5 kx only searching through files that you know have safe names, then you
5 kx need not be concerned about it.
5 kx
5 kx Error messages issued by @code{find} and @code{locate} quote unusual
5 kx characters in file names in order to prevent unwanted changes in the
5 kx terminal's state.
5 kx
5 kx
5 kx @c This example is adapted from:
5 kx @c From: pfalstad@stone.Princeton.EDU (Paul John Falstad)
5 kx @c Newsgroups: comp.unix.shell
5 kx @c Subject: Re: Beware xargs security holes
5 kx @c Date: 16 Oct 90 19:12:06 GMT
5 kx @c
5 kx In many applications, if @code{xargs} botches processing a file
5 kx because its name contains special characters, some data might be lost.
5 kx The importance of this problem depends on the importance of the data
5 kx and whether anyone notices the loss soon enough to correct it.
5 kx However, here is an extreme example of the problems that using
5 kx blank-delimited names can cause. If the following command is run
5 kx daily from @code{cron}, then any user can remove any file on the
5 kx system:
5 kx
5 kx @example
5 kx find / -name '#*' -atime +7 -print | xargs rm
5 kx @end example
5 kx
5 kx For example, you could do something like this:
5 kx
5 kx @example
5 kx eg$ echo > '#
5 kx vmunix'
5 kx @end example
5 kx
5 kx @noindent
5 kx and then @code{cron} would delete @file{/vmunix}, if it ran
5 kx @code{xargs} with @file{/} as its current directory.
5 kx
5 kx To delete other files, for example @file{/u/joeuser/.plan}, you could
5 kx do this:
5 kx
5 kx @example
5 kx eg$ mkdir '#
5 kx '
5 kx eg$ cd '#
5 kx '
5 kx eg$ mkdir u u/joeuser u/joeuser/.plan'
5 kx '
5 kx eg$ echo > u/joeuser/.plan'
5 kx /#foo'
5 kx eg$ cd ..
5 kx eg$ find . -name '#*' -print | xargs echo
5 kx ./# ./# /u/joeuser/.plan /#foo
5 kx @end example
5 kx
5 kx @node Safe File Name Handling
5 kx @subsubsection Safe File Name Handling
5 kx
5 kx Here is how to make @code{find} output file names so that they can be
5 kx used by other programs without being mangled or misinterpreted. You
5 kx can process file names generated this way by giving the @samp{-0} or
5 kx @samp{--null} option to GNU @code{xargs}, GNU @code{tar}, GNU
5 kx @code{cpio}, or @code{perl}.
5 kx
5 kx @deffn Action -print0
5 kx True; print the entire file name on the standard output, followed by a
5 kx null character.
5 kx @end deffn
5 kx
5 kx @deffn Action -fprint0 file
5 kx True; like @samp{-print0} but write to @var{file} like @samp{-fprint}
5 kx (@pxref{Print File Name}). The output file is always created.
5 kx @end deffn
5 kx
5 kx As of findutils version 4.2.4, the @code{locate} program also has a
5 kx @samp{--null} option which does the same thing. For similarity with
5 kx @code{xargs}, the short form of the option @samp{-0} can also be used.
5 kx
5 kx If you want to be able to handle file names safely but need to run
5 kx commands which want to be connected to a terminal on their input, you
5 kx can use the @samp{--open-tty} option to @code{xargs} or the
5 kx @samp{--arg-file} option to @code{xargs} like this:
5 kx
5 kx @example
5 kx find / -name xyzzy -print0 > list
5 kx xargs --null --arg-file=list munge
5 kx @end example
5 kx
5 kx The example above runs the @code{munge} program on all the files named
5 kx @file{xyzzy} that we can find, but @code{munge}'s input will still be
5 kx the terminal (or whatever the shell was using as standard input). If
5 kx your shell has the ``process substitution'' feature @samp{<(...)}, you
5 kx can do this in just one step:
5 kx
5 kx @example
5 kx xargs --null --arg-file=<(find / -name xyzzy -print0) munge
5 kx @end example
5 kx
5 kx @node Unusual Characters in File Names
5 kx @subsubsection Unusual Characters in File Names
5 kx As discussed above, you often need to be careful about how the names
5 kx of files are handled by @code{find} and other programs. If the output
5 kx of @code{find} is not going to another program but instead is being
5 kx shown on a terminal, this can still be a problem. For example, some
5 kx character sequences can reprogram the function keys on some terminals.
5 kx @xref{Security Considerations}, for a discussion of other security
5 kx problems relating to @code{find}.
5 kx
5 kx Unusual characters are handled differently by various
5 kx actions, as described below.
5 kx
5 kx @table @samp
5 kx @item -print0
5 kx @itemx -fprint0
5 kx Always print the exact file name, unchanged, even if the output is
5 kx going to a terminal.
5 kx @item -ok
5 kx @itemx -okdir
5 kx Always print the exact file name, unchanged. This will probably
5 kx change in a future release.
5 kx @item -ls
5 kx @itemx -fls
5 kx Unusual characters are always escaped. White space, backslash, and
5 kx double quote characters are printed using C-style escaping (for
5 kx example @samp{\f}, @samp{\"}). Other unusual characters are printed
5 kx using an octal escape. Other printable characters (for @samp{-ls} and
5 kx @samp{-fls} these are the characters between octal 041 and 0176) are
5 kx printed as-is.
5 kx @item -printf
5 kx @itemx -fprintf
5 kx If the output is not going to a terminal, it is printed as-is.
5 kx Otherwise, the result depends on which directive is in use:
5 kx
5 kx @table @asis
5 kx @item %D, %F, %H, %Y, %y
5 kx These expand to values which are not under control of files' owners,
5 kx and so are printed as-is.
5 kx @item %a, %b, %c, %d, %g, %G, %i, %k, %m, %M, %n, %s, %t, %u, %U
5 kx These have values which are under the control of files' owners but
5 kx which cannot be used to send arbitrary data to the terminal, and so
5 kx these are printed as-is.
5 kx @item %f, %h, %l, %p, %P
5 kx The output of these directives is quoted if the output is going to a
5 kx terminal. The setting of the @code{LC_CTYPE} environment
5 kx variable is used to determine which characters need to be quoted.
5 kx
5 kx This quoting is performed in the same way as for GNU @code{ls}. This
5 kx is not the same quoting mechanism as the one used for @samp{-ls} and
5 kx @samp{fls}. If you are able to decide what format to use for the
5 kx output of @code{find} then it is normally better to use @samp{\0} as a
5 kx terminator than to use newline, as file names can contain white space
5 kx and newline characters.
5 kx @end table
5 kx @item -print
5 kx @itemx -fprint
5 kx Quoting is handled in the same way as for the @samp{%p} directive of
5 kx @samp{-printf} and @samp{-fprintf}. If you are using @code{find} in a
5 kx script or in a situation where the matched files might have arbitrary
5 kx names, you should consider using @samp{-print0} instead of
5 kx @samp{-print}.
5 kx @end table
5 kx
5 kx
5 kx The @code{locate} program quotes and escapes unusual characters in
5 kx file names in the same way as @code{find}'s @samp{-print} action.
5 kx
5 kx The behaviours described above may change soon, as the treatment of
5 kx unprintable characters is harmonised for @samp{-ls}, @samp{-fls},
5 kx @samp{-print}, @samp{-fprint}, @samp{-printf} and @samp{-fprintf}.
5 kx
5 kx @node Limiting Command Size
5 kx @subsubsection Limiting Command Size
5 kx
5 kx @code{xargs} gives you control over how many arguments it passes to
5 kx the command each time it executes it. By default, it uses up to
5 kx @code{ARG_MAX} - 2k, or 128k, whichever is smaller, characters per
5 kx command. It uses as many lines and arguments as fit within that
5 kx limit. The following options modify those values.
5 kx
5 kx @table @code
5 kx @item --no-run-if-empty
5 kx @itemx -r
5 kx If the standard input does not contain any nonblanks, do not run the
5 kx command. By default, the command is run once even if there is no
5 kx input. This option is a GNU extension.
5 kx
5 kx @item --max-lines@r{[}=@var{max-lines}@r{]}
5 kx @itemx -L @var{max-lines}
5 kx @itemx -l@r{[}@var{max-lines}@r{]}
5 kx Use at most @var{max-lines} nonblank input lines per command line;
5 kx @var{max-lines} defaults to 1 if omitted; omitting the argument is not
5 kx allowed in the case of the @samp{-L} option. Trailing blanks cause an
5 kx input line to be logically continued on the next input line, for the
5 kx purpose of counting the lines. Implies @samp{-x}. The preferred name
5 kx for this option is @samp{-L} as this is specified by POSIX.
5 kx
5 kx @item --max-args=@var{max-args}
5 kx @itemx -n @var{max-args}
5 kx Use at most @var{max-args} arguments per command line. Fewer than
5 kx @var{max-args} arguments will be used if the size (see the @samp{-s}
5 kx option) is exceeded, unless the @samp{-x} option is given, in which
5 kx case @code{xargs} will exit.
5 kx
5 kx @item --max-chars=@var{max-chars}
5 kx @itemx -s @var{max-chars}
5 kx Use at most @var{max-chars} characters per command line, including the
5 kx command initial arguments and the terminating nulls at the ends of the
5 kx argument strings. If you specify a value for this option which is too
5 kx large or small, a warning message is printed and the appropriate upper
5 kx or lower limit is used instead. You can use @samp{--show-limits}
5 kx option to understand the command-line limits applying to @code{xargs}
5 kx and how this is affected by any other options. The POSIX limits shown
5 kx when you do this have already been adjusted to take into account the
5 kx size of your environment variables.
5 kx
5 kx The largest allowed value is system-dependent, and is calculated as
5 kx the argument length limit for exec, less the size of your environment,
5 kx less 2048 bytes of headroom. If this value is more than 128KiB,
5 kx 128Kib is used as the default value; otherwise, the default value is
5 kx the maximum.
5 kx @end table
5 kx
5 kx @node Controlling Parallelism
5 kx @subsubsection Controlling Parallelism
5 kx
5 kx Normally, @code{xargs} runs one command at a time. This is called
5 kx "serial" execution; the commands happen in a series, one after another.
5 kx If you'd like @code{xargs} to do things in "parallel", you can ask it
5 kx to do so, either when you invoke it, or later while it is running.
5 kx Running several commands at one time can make the entire operation
5 kx go more quickly, if the commands are independent, and if your system
5 kx has enough resources to handle the load. When parallelism works in
5 kx your application, @code{xargs} provides an easy way to get your work
5 kx done faster.
5 kx
5 kx @table @code
5 kx @item --max-procs=@var{max-procs}
5 kx @itemx -P @var{max-procs}
5 kx Run up to @var{max-procs} processes at a time; the default is 1. If
5 kx @var{max-procs} is 0, @code{xargs} will run as many processes as
5 kx possible at a time. Use the @samp{-n}, @samp{-s}, or @samp{-L} option
5 kx with @samp{-P}; otherwise chances are that the command will be run
5 kx only once.
5 kx @end table
5 kx
5 kx For example, suppose you have a directory tree of large image files
5 kx and a @code{makeallsizes} script that takes a single file name and
5 kx creates various sized images from it (thumbnail-sized, web-page-sized,
5 kx printer-sized, and the original large file). The script is doing enough
5 kx work that it takes significant time to run, even on a single image.
5 kx You could run:
5 kx
5 kx @example
5 kx find originals -name '*.jpg' | xargs -l makeallsizes
5 kx @end example
5 kx
5 kx This will run @code{makeallsizes @var{filename}} once for each @code{.jpg}
5 kx file in the @code{originals} directory. However, if your system has
5 kx two central processors, this script will only keep one of them busy.
5 kx Instead, you could probably finish in about half the time by running:
5 kx
5 kx @example
5 kx find originals -name '*.jpg' | xargs -l -P 2 makeallsizes
5 kx @end example
5 kx
5 kx @code{xargs} will run the first two commands in parallel, and then
5 kx whenever one of them terminates, it will start another one, until
5 kx the entire job is done.
5 kx
5 kx The same idea can be generalized to as many processors as you have handy.
5 kx It also generalizes to other resources besides processors. For example,
5 kx if @code{xargs} is running commands that are waiting for a response from a
5 kx distant network connection, running a few in parallel may reduce the
5 kx overall latency by overlapping their waiting time.
5 kx
5 kx If you are running commands in parallel, you need to think about how
5 kx they should arbitrate access to any resources that they share. For
5 kx example, if more than one of them tries to print to stdout, the output
5 kx will be produced in an indeterminate order (and very likely mixed up)
5 kx unless the processes collaborate in some way to prevent this. Using
5 kx some kind of locking scheme is one way to prevent such problems. In
5 kx general, using a locking scheme will help ensure correct output but
5 kx reduce performance. If you don't want to tolerate the performance
5 kx difference, simply arrange for each process to produce a separate output
5 kx file (or otherwise use separate resources).
5 kx
5 kx @code{xargs} also allows ``turning up'' or ``turning down'' its parallelism
5 kx in the middle of a run. Suppose you are keeping your four-processor
5 kx system busy for hours, processing thousands of images using @code{-P 4}.
5 kx Now, in the middle of the run, you or someone else wants you to reduce
5 kx your load on the system, so that something else will run faster.
5 kx If you interrupt @code{xargs}, your job will be half-done, and it
5 kx may take significant manual work to resume it only for the remaining
5 kx images. If you suspend @code{xargs} using your shell's job controls
5 kx (e.g. @code{control-Z}), then it will get no work done while suspended.
5 kx
5 kx Find out the process ID of the @code{xargs} process, either from your
5 kx shell or with the @code{ps} command. After you send it the signal
5 kx @code{SIGUSR2}, @code{xargs} will run one fewer command in parallel.
5 kx If you send it the signal @code{SIGUSR1}, it will run one more command
5 kx in parallel. For example:
5 kx
5 kx @example
5 kx shell$ xargs <allimages -l -P 4 makeallsizes &
5 kx [4] 27643
5 kx ... at some later point ...
5 kx shell$ kill -USR2 27643
5 kx shell$ kill -USR2 %4
5 kx @end example
5 kx
5 kx The first @code{kill} command will cause @code{xargs} to wait for
5 kx two commands to terminate before starting the next command (reducing
5 kx the parallelism from 4 to 3). The second @code{kill} will reduce it from
5 kx 3 to 2. (@code{%4} works in some shells as a shorthand for the process
5 kx ID of the background job labeled @code{[4]}.)
5 kx
5 kx Similarly, if you started a long @code{xargs} job without parallelism, you
5 kx can easily switch it to start running two commands in parallel by sending
5 kx it a @code{SIGUSR1}.
5 kx
5 kx @code{xargs} will never terminate any existing commands when you ask it
5 kx to run fewer processes. It merely waits for the excess commands to
5 kx finish. If you ask it to run more commands, it will start the next
5 kx one immediately (if it has more work to do). If the degree of
5 kx parallelism is already 1, sending @code{SIGUSR2} will have no further
5 kx effect (since @code{--max-procs=0} means that there should be no limit
5 kx on the number of processes to run).
5 kx
5 kx There is an implementation-defined limit on the number of processes.
5 kx This limit is shown with @code{xargs --show-limits}. The limit is at
5 kx least 127 on all systems (and on the author's system it is
5 kx 2147483647).
5 kx
5 kx If you send several identical signals quickly, the operating system
5 kx does not guarantee that each of them will be delivered to @code{xargs}.
5 kx This means that you can't rapidly increase or decrease the parallelism by
5 kx more than one command at a time. You can avoid this problem by sending
5 kx a signal, observing the result, then sending the next one; or merely by
5 kx delaying for a few seconds between signals (unless your system is very
5 kx heavily loaded).
5 kx
5 kx Whether or not parallel execution will work well for you depends on
5 kx the nature of the commmand you are running in parallel, on the
5 kx configuration of the system on which you are running the command, and
5 kx on the other work being done on the system at the time.
5 kx
5 kx @node Interspersing File Names
5 kx @subsubsection Interspersing File Names
5 kx
5 kx @code{xargs} can insert the name of the file it is processing between
5 kx arguments you give for the command. Unless you also give options to
5 kx limit the command size (@pxref{Limiting Command Size}), this mode of
5 kx operation is equivalent to @samp{find -exec} (@pxref{Single File}).
5 kx
5 kx @table @code
5 kx @item --replace@r{[}=@var{replace-str}@r{]}
5 kx @itemx -I @var{replace-str}
5 kx @itemx -i @var{replace-str}
5 kx Replace occurrences of @var{replace-str} in the initial arguments with
5 kx names read from the input. Also, unquoted blanks do not terminate
5 kx arguments; instead, the input is split at newlines only. For the
5 kx @samp{-i} option, if @var{replace-str} is omitted for @samp{--replace}
5 kx or @samp{-i}, it defaults to @samp{@{@}} (like for @samp{find -exec}).
5 kx Implies @samp{-x} and @samp{-l 1}. @samp{-i} is deprecated in favour
5 kx of @samp{-I}. As an example, to sort each file in the @file{bills}
5 kx directory, leaving the output in that file name with @file{.sorted}
5 kx appended, you could do:
5 kx
5 kx @example
5 kx find bills -type f | xargs -I XX sort -o XX.sorted XX
5 kx @end example
5 kx
5 kx @noindent
5 kx The equivalent command using @samp{find -execdir} is:
5 kx
5 kx @example
5 kx find bills -type f -execdir sort -o '@{@}.sorted' '@{@}' ';'
5 kx @end example
5 kx @end table
5 kx
5 kx
5 kx When you use the @samp{-I} option, each line read from the input is
5 kx buffered internally. This means that there is an upper limit on the
5 kx length of input line that @code{xargs} will accept when used with the
5 kx @samp{-I} option. To work around this limitation, you can use the
5 kx @samp{-s} option to increase the amount of buffer space that xargs
5 kx uses, and you can also use an extra invocation of xargs to ensure that
5 kx very long lines do not occur. For example:
5 kx
5 kx @example
5 kx somecommand | xargs -s 50000 echo | xargs -I '@{@}' -s 100000 rm '@{@}'
5 kx @end example
5 kx
5 kx Here, the first invocation of @code{xargs} has no input line length
5 kx limit because it doesn't use the @samp{-I} option. The second
5 kx invocation of @code{xargs} does have such a limit, but we have ensured
5 kx that it never encounters a line which is longer than it can
5 kx handle.
5 kx
5 kx This is not an ideal solution. Instead, the @samp{-I} option should
5 kx not impose a line length limit (apart from any limit imposed by the
5 kx operating system) and so one might consider this limitation to be a
5 kx bug. A better solution would be to allow @code{xargs -I} to
5 kx automatically move to a larger value for the @samp{-s} option when
5 kx this is needed.
5 kx
5 kx This sort of problem doesn't occur with the output of @code{find}
5 kx because it emits just one filename per line.
5 kx
5 kx @node Querying
5 kx @subsection Querying
5 kx
5 kx To ask the user whether to execute a command on a single file, you can
5 kx use the @code{find} primary @samp{-okdir} instead of @samp{-execdir},
5 kx and the @code{find} primary @samp{-ok} instead of @samp{-exec}:
5 kx
5 kx @deffn Action -okdir command ;
5 kx Like @samp{-execdir} (@pxref{Single File}), but ask the user first.
5 kx If the user does not agree to run the command, just return false.
5 kx Otherwise, run it, with standard input redirected from
5 kx @file{/dev/null}.
5 kx
5 kx The response to the prompt is matched against a pair of regular
5 kx expressions to determine if it is a yes or no response. These regular
5 kx expressions are obtained from the system (@code{nl_langinfo} items
5 kx YESEXPR and NOEXPR are used) if the @code{POSIXLY_CORRECT} environment
5 kx variable is set and the system has such patterns available. Otherwise,
5 kx @code{find}'s message translations are used. In either case, the
5 kx @code{LC_MESSAGES} environment variable will determine the regular
5 kx expressions used to determine if the answer is affirmative or negative.
5 kx The interpretation of the regular expressions themselves will be
5 kx affected by the environment variables @code{LC_CTYPE} (character
5 kx classes) and @code{LC_COLLATE} (character ranges and equivalence
5 kx classes).
5 kx @end deffn
5 kx
5 kx @deffn Action -ok command ;
5 kx This insecure variant of the @samp{-okdir} action is specified by
5 kx POSIX. The main difference is that the command is executed in the
5 kx directory from which @code{find} was invoked, meaning that @samp{@{@}}
5 kx is expanded to a relative path starting with the name of one of the
5 kx starting directories, rather than just the basename of the matched
5 kx file. If the command is run, its standard input is redirected from
5 kx @file{/dev/null}.
5 kx @end deffn
5 kx
5 kx When processing multiple files with a single command, to query the
5 kx user you give @code{xargs} the following option. When using this
5 kx option, you might find it useful to control the number of files
5 kx processed per invocation of the command (@pxref{Limiting Command
5 kx Size}).
5 kx
5 kx @table @code
5 kx @item --interactive
5 kx @itemx -p
5 kx Prompt the user about whether to run each command line and read a line
5 kx from the terminal. Only run the command line if the response starts
5 kx with @samp{y} or @samp{Y}. Implies @samp{-t}.
5 kx @end table
5 kx
5 kx @node Delete Files
5 kx @section Delete Files
5 kx
5 kx @deffn Action -delete
5 kx Delete files or directories; true if removal succeeded. If the
5 kx removal failed, an error message is issued.
5 kx
5 kx The use of the @samp{-delete} action on the command line automatically
5 kx turns on the @samp{-depth} option (@pxref{find Expressions}). This
5 kx can be surprising if you were previously just testing with
5 kx @samp{-print}, so it is usually best to remember to use @samp{-depth}
5 kx explicitly.
5 kx
5 kx If @samp{-delete} fails, @code{find}'s exit status will be nonzero
5 kx (when it eventually exits).
5 kx
5 kx Together with the @samp{-ignore_readdir_race} option, @code{find} will
5 kx ignore errors of the @samp{-delete} action in the case the file has disappeared
5 kx since the parent directory was read: it will not output an error diagnostic, and
5 kx the return code of the @samp{-delete} action will be true.
5 kx @end deffn
5 kx
5 kx @node Adding Tests
5 kx @section Adding Tests
5 kx
5 kx You can test for file attributes that none of the @code{find} builtin
5 kx tests check. To do this, use @code{xargs} to run a program that
5 kx filters a list of files printed by @code{find}. If possible, use
5 kx @code{find} builtin tests to pare down the list, so the program run by
5 kx @code{xargs} has less work to do. The tests builtin to @code{find}
5 kx will likely run faster than tests that other programs perform.
5 kx
5 kx For reasons of efficiency it is often useful to limit the number of
5 kx times an external program has to be run. For this reason, it is often
5 kx a good idea to implement ``extended'' tests by using @code{xargs}.
5 kx
5 kx For example, here is a way to print the names of all of the unstripped
5 kx binaries in the @file{/usr/local} directory tree. Builtin tests avoid
5 kx running @code{file} on files that are not regular files or are not
5 kx executable.
5 kx
5 kx @example
5 kx find /usr/local -type f -perm /a=x | xargs file |
5 kx grep 'not stripped' | cut -d: -f1
5 kx @end example
5 kx
5 kx @noindent
5 kx The @code{cut} program removes everything after the file name from the
5 kx output of @code{file}.
5 kx
5 kx However, using @code{xargs} can present important security problems
5 kx (@pxref{Security Considerations}). These can be avoided by using
5 kx @samp{-execdir}. The @samp{-execdir} action is also a useful way of
5 kx putting your own test in the middle of a set of other tests or actions
5 kx for @code{find} (for example, you might want to use @samp{-prune}).
5 kx
5 kx @c Idea from Martin Weitzel.
5 kx To place a special test somewhere in the middle of a @code{find}
5 kx expression, you can use @samp{-execdir} (or, less securely,
5 kx @samp{-exec}) to run a program that performs the test. Because
5 kx @samp{-execdir} evaluates to the exit status of the executed program,
5 kx you can use a program (which can be a shell script) that tests for a
5 kx special attribute and make it exit with a true (zero) or false
5 kx (non-zero) status. It is a good idea to place such a special test
5 kx @emph{after} the builtin tests, because it starts a new process which
5 kx could be avoided if a builtin test evaluates to false.
5 kx
5 kx Here is a shell script called @code{unstripped} that checks whether
5 kx its argument is an unstripped binary file:
5 kx
5 kx @example
5 kx #! /bin/sh
5 kx file "$1" | grep -q "not stripped"
5 kx @end example
5 kx
5 kx
5 kx This script relies on the shell exiting with the status of
5 kx the last command in the pipeline, in this case @code{grep}. The
5 kx @code{grep} command exits with a true status if it found any matches,
5 kx false if not. Here is an example of using the script (assuming it is
5 kx in your search path). It lists the stripped executables (and shell
5 kx scripts) in the file @file{sbins} and the unstripped ones in
5 kx @file{ubins}.
5 kx
5 kx @example
5 kx find /usr/local -type f -perm /a=x \
5 kx \( -execdir unstripped '@{@}' \; -fprint ubins -o -fprint sbins \)
5 kx @end example
5 kx
5 kx
5 kx @node Databases
5 kx @chapter File Name Databases
5 kx
5 kx The file name databases used by @code{locate} contain lists of files
5 kx that were in particular directory trees when the databases were last
5 kx updated. The file name of the default database is determined when
5 kx @code{locate} and @code{updatedb} are configured and installed. The
5 kx frequency with which the databases are updated and the directories for
5 kx which they contain entries depend on how often @code{updatedb} is run,
5 kx and with which arguments.
5 kx
5 kx You can obtain some statistics about the databases by using
5 kx @samp{locate --statistics}.
5 kx
5 kx @menu
5 kx * Database Locations::
5 kx * Database Formats::
5 kx * Newline Handling::
5 kx @end menu
5 kx
5 kx
5 kx @node Database Locations
5 kx @section Database Locations
5 kx
5 kx There can be multiple file name databases. Users can select which
5 kx databases @code{locate} searches using the @code{LOCATE_PATH}
5 kx environment variable or a command line option. The system
5 kx administrator can choose the file name of the default database, the
5 kx frequency with which the databases are updated, and the directories
5 kx for which they contain entries. File name databases are updated by
5 kx running the @code{updatedb} program, typically nightly.
5 kx
5 kx In networked environments, it often makes sense to build a database at
5 kx the root of each filesystem, containing the entries for that
5 kx filesystem. @code{updatedb} is then run for each filesystem on the
5 kx fileserver where that filesystem is on a local disk, to prevent
5 kx thrashing the network.
5 kx
5 kx @xref{Invoking updatedb}, for the description of the options to
5 kx @code{updatedb}. These options can be used to specify which
5 kx directories are indexed by each database file.
5 kx
5 kx The default location for the locate database depends on how findutils
5 kx is built, but the findutils installation accompanying this manual uses
5 kx the default location @file{@value{LOCATE_DB}}.
5 kx
5 kx If no database exists at @file{@value{LOCATE_DB}} but the user did not
5 kx specify where to look (by using @samp{-d} or setting
5 kx @code{LOCATE_PATH}), then @code{locate} will also check for a
5 kx ``secure'' database in @file{/var/lib/slocate/slocate.db}.
5 kx
5 kx @node Database Formats
5 kx @section Database Formats
5 kx
5 kx The file name databases contain lists of files that were in particular
5 kx directory trees when the databases were last updated. The file name
5 kx database format changed starting with GNU @code{locate} version 4.0 to
5 kx allow machines with different byte orderings to share the databases.
5 kx
5 kx GNU @code{locate} can read both the old pre-findutils-4.0 database
5 kx format and the @samp{LOCATE02} database format. Support for the old
5 kx database format will shortly be removed from @code{locate}. It has
5 kx already been removed from @code{updatedb}.
5 kx
5 kx If you run @samp{locate --statistics}, the resulting summary indicates
5 kx the type of each @code{locate} database. You select which database
5 kx format @code{updatedb} will use with the @samp{--dbformat} option.
5 kx
5 kx The @samp{slocate} database format is very similar to @samp{LOCATE02}
5 kx and is also supported (in both @code{updatedb} and @code{locate}).
5 kx
5 kx @menu
5 kx * LOCATE02 Database Format::
5 kx * Sample LOCATE02 Database::
5 kx * slocate Database Format::
5 kx * Old Database Format::
5 kx @end menu
5 kx
5 kx @node LOCATE02 Database Format
5 kx @subsection LOCATE02 Database Format
5 kx
5 kx @code{updatedb} runs a program called @code{frcode} to
5 kx @dfn{front-compress} the list of file names, which reduces the
5 kx database size by a factor of 4 to 5. Front-compression (also known as
5 kx incremental encoding) works as follows.
5 kx
5 kx The database entries are a sorted list (case-insensitively, for users'
5 kx convenience). Since the list is sorted, each entry is likely to share
5 kx a prefix (initial string) with the previous entry. Each database
5 kx entry begins with an offset-differential count byte, which is the
5 kx additional number of characters of prefix of the preceding entry to
5 kx use beyond the number that the preceding entry is using of its
5 kx predecessor. (The counts can be negative.) Following the count is a
5 kx null-terminated ASCII remainder -- the part of the name that follows
5 kx the shared prefix.
5 kx
5 kx If the offset-differential count is larger than can be stored in a
5 kx byte (+/-127), the byte has the value 0x80 and the count follows in a
5 kx 2-byte word, with the high byte first (network byte order).
5 kx
5 kx Every database begins with a dummy entry for a file called
5 kx @file{LOCATE02}, which @code{locate} checks for to ensure that the
5 kx database file has the correct format; it ignores the entry in doing
5 kx the search.
5 kx
5 kx Databases cannot be concatenated together, even if the first (dummy)
5 kx entry is trimmed from all but the first database. This is because the
5 kx offset-differential count in the first entry of the second and
5 kx following databases will be wrong.
5 kx
5 kx In the output of @samp{locate --statistics}, the new database format
5 kx is referred to as @samp{LOCATE02}.
5 kx
5 kx @node Sample LOCATE02 Database
5 kx @subsection Sample LOCATE02 Database
5 kx
5 kx Sample input to @code{frcode}:
5 kx @c with nulls changed to newlines:
5 kx
5 kx @example
5 kx /usr/src
5 kx /usr/src/cmd/aardvark.c
5 kx /usr/src/cmd/armadillo.c
5 kx /usr/tmp/zoo
5 kx @end example
5 kx
5 kx Length of the longest prefix of the preceding entry to share:
5 kx
5 kx @example
5 kx 0 /usr/src
5 kx 8 /cmd/aardvark.c
5 kx 14 rmadillo.c
5 kx 5 tmp/zoo
5 kx @end example
5 kx
5 kx Output from @code{frcode}, with trailing nulls changed to newlines
5 kx and count bytes made printable:
5 kx
5 kx @example
5 kx 0 LOCATE02
5 kx 0 /usr/src
5 kx 8 /cmd/aardvark.c
5 kx 6 rmadillo.c
5 kx -9 tmp/zoo
5 kx @end example
5 kx
5 kx (6 = 14 - 8, and -9 = 5 - 14)
5 kx
5 kx @node slocate Database Format
5 kx @subsection slocate Database Format
5 kx
5 kx The @code{slocate} program uses a database format similar to, but not
5 kx quite the same as, GNU @code{locate}. The first byte of the database
5 kx specifies its @dfn{security level}. If the security level is 0,
5 kx @code{slocate} will read, match and print filenames on the basis of
5 kx the information in the database only. However, if the security level
5 kx byte is 1, @code{slocate} omits entries from its output if the
5 kx invoking user is unable to access them. The second byte of the
5 kx database is zero. The second byte is immediately followed by the
5 kx first database entry. The first entry in the database is not preceded
5 kx by any differential count or dummy entry. Instead the differential
5 kx count for the first item is assumed to be zero.
5 kx
5 kx Starting with the second entry (if any) in the database, data is
5 kx interpreted as for the GNU LOCATE02 format.
5 kx
5 kx @node Old Database Format
5 kx @subsection Old Database Format
5 kx
5 kx The old database format is used by Unix @code{locate} and @code{find}
5 kx programs and pre-4.0 releases of GNU findutils. @code{locate}
5 kx understands this format, though @code{updatedb} will no longer produce
5 kx it.
5 kx
5 kx The old format differs from @samp{LOCATE02} in the following ways.
5 kx Instead of each entry starting with an offset-differential count byte
5 kx and ending with a null, byte values from 0 through 28 indicate
5 kx offset-differential counts from -14 through 14. The byte value
5 kx indicating that a long offset-differential count follows is 0x1e (30),
5 kx not 0x80. The long counts are stored in host byte order, which is not
5 kx necessarily network byte order, and host integer word size, which is
5 kx usually 4 bytes. They also represent a count 14 less than their
5 kx value. The database lines have no termination byte; the start of the
5 kx next line is indicated by its first byte having a value <= 30.
5 kx
5 kx In addition, instead of starting with a dummy entry, the old database
5 kx format starts with a 256 byte table containing the 128 most common
5 kx bigrams in the file list. A bigram is a pair of adjacent bytes.
5 kx Bytes in the database that have the high bit set are indexes (with the
5 kx high bit cleared) into the bigram table. The bigram and
5 kx offset-differential count coding makes these databases 20-25% smaller
5 kx than the new format, but makes them not 8-bit clean. Any byte in a
5 kx file name that is in the ranges used for the special codes is replaced
5 kx in the database by a question mark, which not coincidentally is the
5 kx shell wildcard to match a single character. The old format therefore
5 kx cannot faithfully store entries with non-ASCII characters.
5 kx
5 kx Because the long counts are stored as
5 kx native-order machine words, the database format is not easily used in
5 kx environments which differ in terms of byte order. If locate databases
5 kx are to be shared between machines, the @samp{LOCATE02} database format should
5 kx be used. This has other benefits as discussed above. However, the
5 kx length of the filename currently being processed can normally be used
5 kx to place reasonable limits on the long counts and so this information
5 kx is used by locate to help it guess the byte ordering of the old format
5 kx database. Unless it finds evidence to the contrary, @code{locate}
5 kx will assume that the byte order of the database is the same as the
5 kx native byte order of the machine running @code{locate}. The output of
5 kx @samp{locate --statistics} also includes information about the byte
5 kx order of old-format databases.
5 kx
5 kx The output of @samp{locate --statistics} will give an incorrect count
5 kx of the number of file names containing newlines or high-bit characters
5 kx for old-format databases.
5 kx
5 kx Old versions of GNU @code{locate} fail to correctly handle very long
5 kx file names, possibly leading to security problems relating to a heap
5 kx buffer overrun. @xref{Security Considerations for locate}, for a
5 kx detailed explanation.
5 kx
5 kx @node Newline Handling
5 kx @section Newline Handling
5 kx
5 kx Within the database, file names are terminated with a null character.
5 kx This is the case for both the old and the new format.
5 kx
5 kx When the new database format is being used, the compression technique
5 kx used to generate the database though relies on the ability to sort the
5 kx list of files before they are presented to @code{frcode}.
5 kx
5 kx If the system's sort command allows separating its input list of
5 kx files with null characters via the @samp{-z} option, this option
5 kx is used and therefore @code{updatedb} and @code{locate} will both
5 kx correctly handle file names containing newlines. If the @code{sort}
5 kx command lacks support for this, the list of files is delimited with
5 kx the newline character, meaning that parts of file names containing
5 kx newlines will be incorrectly sorted. This can result in both
5 kx incorrect matches and incorrect failures to match.
5 kx
5 kx @node File Permissions
5 kx @chapter File Permissions
5 kx
5 kx @include perm.texi
5 kx
5 kx @include parse-datetime.texi
5 kx
5 kx @node Configuration
5 kx @chapter Configuration
5 kx
5 kx The findutils source distribution includes a @code{configure} script
5 kx which examines the system and generates files required to build
5 kx findutils. See the files @file{README} and @file{INSTALL}.
5 kx
5 kx A number of options can be specified on the @code{configure} command
5 kx line, and many of these are straightforward, adequately documented in
5 kx the @code{--help} output, or not normally useful. Options which are
5 kx useful or which are not obvious are explained here.
5 kx
5 kx @menu
5 kx * Leaf Optimisation:: Take advantage of Unix file system semantics.
5 kx * d_type Optimisation:: Take advantage of file type information.
5 kx @end menu
5 kx
5 kx @node Leaf Optimisation
5 kx @section Leaf Optimisation
5 kx
5 kx Files in Unix file systems have a link count which indicates how many
5 kx names point to the same inode. Directories in Unix filssytems have a
5 kx @file{..} entry which functions as a hard link to the parent directory
5 kx and a @file{.} entry which functions as a link to the directory itself.
5 kx The @file{..} entry of the root directory also points to the root.
5 kx This means that @code{find} can deduce the number of subdirectories a
5 kx directory has, simply by subtracting 2 from the directory's link
5 kx count. This allows @file{find} saving @code{stat} calls which would
5 kx otherwise be needed to discover which directory entries are
5 kx subdirectories.
5 kx
5 kx File systems which don't have these semantics should simply return a
5 kx value less than 2 in the @code{st_nlinks} member of @code{struct stat}
5 kx in response to a successful call to @code{stat}.
5 kx
5 kx If you are building @code{find} for a system on which the value of
5 kx @code{st_nlinks} is unreliable, you can specify
5 kx @code{--disable-leaf-optimisation} to @code{configure} to prevent this
5 kx assumption being made.
5 kx
5 kx @node d_type Optimisation
5 kx @section d_type Optimisation
5 kx
5 kx When this feature is enabled, @code{find} takes advantage of the fact
5 kx that on some systems @code{readdir} will return the type of a file in
5 kx @code{struct dirent}.
5 kx
5 kx
5 kx @node Reference
5 kx @chapter Reference
5 kx
5 kx Below are summaries of the command line syntax for the programs
5 kx discussed in this manual.
5 kx
5 kx @menu
5 kx * Invoking find::
5 kx * Invoking locate::
5 kx * Invoking updatedb::
5 kx * Invoking xargs::
5 kx * Regular Expressions::
5 kx * Environment Variables::
5 kx @end menu
5 kx
5 kx @node Invoking find
5 kx @section Invoking @code{find}
5 kx
5 kx @example
5 kx find @r{[-H] [-L] [-P] [-D @var{debugoptions}] [-O@var{level}]} @r{[}@var{file}@dots{}@r{]} @r{[}@var{expression}@r{]}
5 kx @end example
5 kx
5 kx @code{find} searches the directory tree rooted at each file name
5 kx @var{file} by evaluating the @var{expression} on each file it finds in
5 kx the tree.
5 kx
5 kx The command line may begin with the @samp{-H}, @samp{-L}, @samp{-P},
5 kx @samp{-D} and @samp{-O} options. These are followed by a list of
5 kx files or directories that should be searched. If no files to search
5 kx are specified, the current directory (@file{.}) is used.
5 kx
5 kx This list of files to search is followed by a list of expressions
5 kx describing the files we wish to search for. The first part of the
5 kx expression is recognised by the fact that it begins with @samp{-}
5 kx followed by some other letters (for example @samp{-print}), or is
5 kx either @samp{(} or @samp{!}. Any arguments after it are the rest of
5 kx the expression.
5 kx
5 kx If no expression is given, the expression @samp{-print} is used.
5 kx
5 kx The @code{find} command exits with status zero if all files matched
5 kx are processed successfully, greater than zero if errors occur.
5 kx
5 kx The @code{find} program also recognises two options for administrative
5 kx use:
5 kx
5 kx @table @samp
5 kx @item --help
5 kx Print a summary of the command line usage and exit.
5 kx @item --version
5 kx Print the version number of @code{find} and exit.
5 kx @end table
5 kx
5 kx The @samp{-version} option is a synonym for @samp{--version}
5 kx
5 kx
5 kx @menu
5 kx * Filesystem Traversal Options::
5 kx * Warning Messages::
5 kx * Optimisation Options::
5 kx * Debug Options::
5 kx * Find Expressions::
5 kx @end menu
5 kx
5 kx @node Filesystem Traversal Options
5 kx @subsection Filesystem Traversal Options
5 kx
5 kx The options @samp{-H}, @samp{-L} or @samp{-P} may be specified at the
5 kx start of the command line (if none of these is specified, @samp{-P} is
5 kx assumed). If you specify more than one of these options, the last one
5 kx specified takes effect (but note that the @samp{-follow} option is
5 kx equivalent to @samp{-L}).
5 kx
5 kx @table @code
5 kx @item -P
5 kx Never follow symbolic links (this is the default), except in the case
5 kx of the @samp{-xtype} predicate.
5 kx @item -L
5 kx Always follow symbolic links, except in the case of the @samp{-xtype}
5 kx predicate.
5 kx @item -H
5 kx Follow symbolic links specified in the list of files to search, or
5 kx which are otherwise specified on the command line.
5 kx @end table
5 kx
5 kx If @code{find} would follow a symbolic link, but cannot for any reason
5 kx (for example, because it has insufficient permissions or the link is
5 kx broken), it falls back on using the properties of the symbolic link
5 kx itself. @ref{Symbolic Links} for a more complete description of how
5 kx symbolic links are handled.
5 kx
5 kx @node Warning Messages
5 kx @subsection Warning Messages
5 kx
5 kx If there is an error on the @code{find} command line, an error message
5 kx is normally issued. However, there are some usages that are
5 kx inadvisable but which @code{find} should still accept. Under these
5 kx circumstances, @code{find} may issue a warning message.
5 kx
5 kx By default, warnings are enabled only if @code{find} is being run
5 kx interactively (specifically, if the standard input is a terminal) and
5 kx the @code{POSIXLY_CORRECT} environment variable is not set. Warning
5 kx messages can be controlled explicitly by the use of options on the
5 kx command line:
5 kx
5 kx @table @code
5 kx @item -warn
5 kx Issue warning messages where appropriate.
5 kx @item -nowarn
5 kx Do not issue warning messages.
5 kx @end table
5 kx
5 kx These options take effect at the point on the command line where they
5 kx are specified. Therefore it's not useful to specify @samp{-nowarn} at
5 kx the end of the command line. The warning messages affected by the
5 kx above options are triggered by:
5 kx
5 kx @itemize @minus
5 kx @item
5 kx Use of the @samp{-d} option which is deprecated; please use
5 kx @samp{-depth} instead, since the latter is POSIX-compliant.
5 kx @item
5 kx Specifying an option (for example @samp{-mindepth}) after a non-option
5 kx (for example @samp{-type} or @samp{-print}) on the command line.
5 kx @item
5 kx Use of the @samp{-name} or @samp{-iname} option with a slash character
5 kx in the pattern. Since the name predicates only compare against the
5 kx basename of the visited files, the only file that can match a slash is
5 kx the root directory itself.
5 kx @end itemize
5 kx
5 kx The default behaviour above is designed to work in that way so that
5 kx existing shell scripts don't generate spurious errors, but people will
5 kx be made aware of the problem.
5 kx
5 kx Some warning messages are issued for less common or more serious
5 kx problems, and consequently cannot be turned off:
5 kx
5 kx @itemize @minus
5 kx @item
5 kx Use of an unrecognised backslash escape sequence with @samp{-fprintf}
5 kx @item
5 kx Use of an unrecognised formatting directive with @samp{-fprintf}
5 kx @end itemize
5 kx
5 kx @node Optimisation Options
5 kx @subsection Optimisation Options
5 kx
5 kx The @samp{-O@var{level}} option sets @code{find}'s optimisation level
5 kx to @var{level}. The default optimisation level is 1.
5 kx
5 kx At certain optimisation levels, @code{find} reorders tests to speed up
5 kx execution while preserving the overall effect; that is, predicates
5 kx with side effects are not reordered relative to each other. The
5 kx optimisations performed at each optimisation level are as follows.
5 kx
5 kx @table @samp
5 kx @item 0
5 kx Currently equivalent to optimisation level 1.
5 kx
5 kx @item 1
5 kx This is the default optimisation level and corresponds to the
5 kx traditional behaviour. Expressions are reordered so that tests based
5 kx only on the names of files (for example@samp{ -name} and
5 kx @samp{-regex}) are performed first.
5 kx
5 kx @item 2
5 kx Any @samp{-type} or @samp{-xtype} tests are performed after any tests
5 kx based only on the names of files, but before any tests that require
5 kx information from the inode. On many modern versions of Unix, file
5 kx types are returned by @code{readdir()} and so these predicates are
5 kx faster to evaluate than predicates which need to stat the file first.
5 kx
5 kx If you use the @samp{-fstype FOO} predicate and specify a filsystem
5 kx type @samp{FOO} which is not known (that is, present in
5 kx @file{/etc/mtab}) at the time @code{find} starts, that predicate is
5 kx equivalent to @samp{-false}.
5 kx
5 kx
5 kx @item 3
5 kx At this optimisation level, the full cost-based query optimiser is
5 kx enabled. The order of tests is modified so that cheap (i.e., fast)
5 kx tests are performed first and more expensive ones are performed later,
5 kx if necessary. Within each cost band, predicates are evaluated earlier
5 kx or later according to whether they are likely to succeed or not. For
5 kx @samp{-o}, predicates which are likely to succeed are evaluated
5 kx earlier, and for @samp{-a}, predicates which are likely to fail are
5 kx evaluated earlier.
5 kx @end table
5 kx
5 kx
5 kx @node Debug Options
5 kx @subsection Debug Options
5 kx
5 kx The @samp{-D} option makes @code{find} produce diagnostic output.
5 kx Much of the information is useful only for diagnosing problems, and so
5 kx most people will not find this option helpful.
5 kx
5 kx The list of debug options should be comma separated. Compatibility of
5 kx the debug options is not guaranteed between releases of findutils.
5 kx For a complete list of valid debug options, see the output of
5 kx @code{find -D help}.
5 kx
5 kx Valid debug options include:
5 kx @table @samp
5 kx @item tree
5 kx Show the expression tree in its original and optimised form.
5 kx @item stat
5 kx Print messages as files are examined with the stat and lstat system
5 kx calls. The find program tries to minimise such calls.
5 kx @item opt
5 kx Prints diagnostic information relating to the optimisation of the
5 kx expression tree; see the @samp{-O} option.
5 kx @item rates
5 kx Prints a summary indicating how often each predicate succeeded or
5 kx failed.
5 kx @item all
5 kx Enable all of the other debug options (but @samp{help}).
5 kx @item help
5 kx Explain the debugging options.
5 kx @end table
5 kx
5 kx @node Find Expressions
5 kx @subsection Find Expressions
5 kx
5 kx The final part of the @code{find} command line is a list of
5 kx expressions. @xref{Primary Index}, for a summary of all of the tests,
5 kx actions, and options that the expression can contain. If the
5 kx expression is missing, @samp{-print} is assumed.
5 kx
5 kx @node Invoking locate
5 kx @section Invoking @code{locate}
5 kx
5 kx @example
5 kx locate @r{[}@var{option}@dots{}@r{]} @var{pattern}@dots{}
5 kx @end example
5 kx
5 kx For each @var{pattern} given @code{locate} searches one or more file
5 kx name databases returning each match of @var{pattern}.
5 kx
5 kx @table @code
5 kx @item --all
5 kx @itemx -A
5 kx Print only names which match all non-option arguments, not those
5 kx matching one or more non-option arguments.
5 kx
5 kx @item --basename
5 kx @itemx -b
5 kx The specified pattern is matched against just the last component of
5 kx the name of a file in the @code{locate} database. This last
5 kx component is also called the ``base name''. For example, the base
5 kx name of @file{/tmp/mystuff/foo.old.c} is @file{foo.old.c}. If the
5 kx pattern contains metacharacters, it must match the base name exactly.
5 kx If not, it must match part of the base name.
5 kx
5 kx @item --count
5 kx @itemx -c
5 kx Instead of printing the matched file names, just print the total
5 kx number of matches found, unless @samp{--print} (@samp{-p}) is also
5 kx present.
5 kx
5 kx
5 kx @item --database=@var{path}
5 kx @itemx -d @var{path}
5 kx Instead of searching the default @code{locate} database
5 kx @file{@value{LOCATE_DB}}, @code{locate} searches the file
5 kx name databases in @var{path}, which is a colon-separated list of
5 kx database file names. You can also use the environment variable
5 kx @code{LOCATE_PATH} to set the list of database files to search. The
5 kx option overrides the environment variable if both are used. Empty
5 kx elements in @var{path} (that is, a leading or trailing colon, or two
5 kx colons in a row) are taken to stand for the default database.
5 kx A database can be supplied on stdin, using @samp{-} as an element
5 kx of @samp{path}. If more than one element of @samp{path} is @samp{-},
5 kx later instances are ignored (but a warning message is printed).
5 kx
5 kx @item --existing
5 kx @itemx -e
5 kx Only print out such names which currently exist (instead of such names
5 kx which existed when the database was created). Note that this may slow
5 kx down the program a lot, if there are many matches in the database.
5 kx The way in which broken symbolic links are treated is affected by the
5 kx @samp{-L}, @samp{-P} and @samp{-H} options. Please note that it is
5 kx possible for the file to be deleted after @code{locate} has checked
5 kx that it exists, but before you use it. This option is automatically
5 kx turned on when reading an @code{slocate} database in secure mode
5 kx (@pxref{slocate Database Format}).
5 kx
5 kx @item --non-existing
5 kx @itemx -E
5 kx Only print out such names which currently do not exist (instead of
5 kx such names which existed when the database was created). Note that
5 kx this may slow down the program a lot, if there are many matches in the
5 kx database. The way in which broken symbolic links are treated is
5 kx affected by the @samp{-L}, @samp{-P} and @samp{-H} options. Please
5 kx note that @code{locate} checks that the file does not exist, but a
5 kx file of the same name might be created after @code{locate}'s check but
5 kx before you read @code{locate}'s output.
5 kx
5 kx @item --follow
5 kx @itemx -L
5 kx If testing for the existence of files (with the @samp{-e} or @samp{-E}
5 kx options), consider broken symbolic links to be non-existing. This is
5 kx the default behaviour.
5 kx
5 kx @item --nofollow
5 kx @itemx -P
5 kx @itemx -H
5 kx If testing for the existence of files (with the @samp{-e} or @samp{-E}
5 kx options), treat broken symbolic links as if they were existing files.
5 kx The @samp{-H} form of this option is provided purely for similarity
5 kx with @code{find}; the use of @samp{-P} is recommended over @samp{-H}.
5 kx
5 kx @item --ignore-case
5 kx @itemx -i
5 kx Ignore case distinctions in both the pattern and the file names.
5 kx
5 kx @item --limit=N
5 kx @itemx -l N
5 kx Limit the number of results printed to N. When used with the
5 kx @samp{--count} option, the value printed will never be larger than
5 kx this limit.
5 kx @item --max-database-age=D
5 kx Normally, @code{locate} will issue a warning message when it searches
5 kx a database which is more than 8 days old. This option changes that
5 kx value to something other than 8. The effect of specifying a negative
5 kx value is undefined.
5 kx @item --mmap
5 kx @itemx -m
5 kx Accepted but does nothing. The option is supported only to provide
5 kx compatibility with BSD's @code{locate}.
5 kx
5 kx @item --null
5 kx @itemx -0
5 kx Results are separated with the ASCII NUL character rather than the
5 kx newline character. To get the full benefit of this option,
5 kx use the new @code{locate} database format (that is the default
5 kx anyway).
5 kx
5 kx @item --print
5 kx @itemx -p
5 kx Print search results when they normally would not be due to
5 kx use of @samp{--statistics} (@samp{-S}) or @samp{--count}
5 kx (@samp{-c}).
5 kx
5 kx @item --wholename
5 kx @itemx -w
5 kx The specified pattern is matched against the whole name of the file in
5 kx the @code{locate} database. If the pattern contains metacharacters,
5 kx it must match exactly. If not, it must match part of the whole file
5 kx name. This is the default behaviour.
5 kx
5 kx @item --regex
5 kx @itemx -r
5 kx Instead of using substring or shell glob matching, the pattern
5 kx specified on the command line is understood to be a regular
5 kx expression. GNU Emacs-style regular expressions are assumed unless
5 kx the @samp{--regextype} option is also given. File names from the
5 kx @code{locate} database are matched using the specified regular
5 kx expression. If the @samp{-i} flag is also given, matching is
5 kx case-insensitive. Matches are performed against the whole path name,
5 kx and so by default a pathname will be matched if any part of it matches
5 kx the specified regular expression. The regular expression may use
5 kx @samp{^} or @samp{$} to anchor a match at the beginning or end of a
5 kx pathname.
5 kx
5 kx @item --regextype
5 kx This option changes the regular expression syntax and behaviour used
5 kx by the @samp{--regex} option. @ref{Regular Expressions} for more
5 kx information on the regular expression dialects understood by GNU
5 kx findutils.
5 kx
5 kx @item --stdio
5 kx @itemx -s
5 kx Accepted but does nothing. The option is supported only to provide
5 kx compatibility with BSD's @code{locate}.
5 kx
5 kx @item --statistics
5 kx @itemx -S
5 kx Print some summary information for each @code{locate} database. No
5 kx search is performed unless non-option arguments are given.
5 kx Although the BSD version of locate also has this option, the format of the
5 kx output is different.
5 kx
5 kx @item --help
5 kx Print a summary of the command line usage for @code{locate} and exit.
5 kx
5 kx @item --version
5 kx Print the version number of @code{locate} and exit.
5 kx @end table
5 kx
5 kx @node Invoking updatedb
5 kx @section Invoking @code{updatedb}
5 kx
5 kx @example
5 kx updatedb @r{[}@var{option}@dots{}@r{]}
5 kx @end example
5 kx
5 kx @code{updatedb} creates and updates the database of file names used by
5 kx @code{locate}. @code{updatedb} generates a list of files similar to
5 kx the output of @code{find} and then uses utilities for optimizing the
5 kx database for performance. @code{updatedb} is often run periodically
5 kx as a @code{cron} job and configured with environment variables or
5 kx command options. Typically, operating systems have a shell script
5 kx that ``exports'' configurations for variable definitions and uses
5 kx another shell script that ``sources'' the configuration file into the
5 kx environment and then executes @code{updatedb} in the environment.
5 kx
5 kx @table @code
5 kx @item --findoptions='@var{OPTION}@dots{}'
5 kx Global options to pass on to @code{find}.
5 kx The environment variable @code{FINDOPTIONS} also sets this value.
5 kx Default is none.
5 kx
5 kx @item --localpaths='@var{path}@dots{}'
5 kx Non-network directories to put in the database.
5 kx Default is @file{/}.
5 kx
5 kx @item --netpaths='@var{path}@dots{}'
5 kx Network (NFS, AFS, RFS, etc.) directories to put in the database.
5 kx The environment variable @code{NETPATHS} also sets this value.
5 kx Default is none.
5 kx
5 kx @item --prunepaths='@var{path}@dots{}'
5 kx Directories to omit from the database, which would otherwise be
5 kx included. The environment variable @code{PRUNEPATHS} also sets this
5 kx value. Default is @file{/tmp /usr/tmp /var/tmp /afs}. The paths are
5 kx used as regular expressions (with @code{find ... -regex}, so you need
5 kx to specify these paths in the same way that @code{find} will encounter
5 kx them. This means for example that the paths must not include trailing
5 kx slashes.
5 kx
5 kx @item --prunefs='@var{path}@dots{}'
5 kx Filesystems to omit from the database, which would otherwise be
5 kx included. Note that files are pruned when a filesystem is reached;
5 kx Any filesystem mounted under an undesired filesystem will be ignored.
5 kx The environment variable @code{PRUNEFS} also sets this value. Default
5 kx is @file{nfs NFS proc}.
5 kx
5 kx @item --output=@var{dbfile}
5 kx The database file to build. The default is system-dependent, but
5 kx when this document was formatted it was @file{@value{LOCATE_DB}}.
5 kx
5 kx @item --localuser=@var{user}
5 kx The user to search the non-network directories as, using @code{su}.
5 kx Default is to search the non-network directories as the current user.
5 kx You can also use the environment variable @code{LOCALUSER} to set this user.
5 kx
5 kx @item --netuser=@var{user}
5 kx The user to search network directories as, using @code{su}. Default
5 kx @code{user} is @code{daemon}. You can also use the environment variable
5 kx @code{NETUSER} to set this user.
5 kx
5 kx @item --dbformat=@var{FORMAT}
5 kx Generate the locate database in format @code{FORMAT}. Supported
5 kx database formats include @code{LOCATE02} (which is the default) and
5 kx @code{slocate}. The @code{slocate} format exists for compatibility
5 kx with @code{slocate}. @xref{Database Formats}, for a detailed
5 kx description of each format.
5 kx
5 kx @item --help
5 kx Print a summary of the command line usage and exit.
5 kx @item --version
5 kx Print the version number of @code{updatedb} and exit.
5 kx @end table
5 kx
5 kx @node Invoking xargs
5 kx @section Invoking @code{xargs}
5 kx
5 kx @example
5 kx xargs @r{[}@var{option}@dots{}@r{]} @r{[}@var{command} @r{[}@var{initial-arguments}@r{]}@r{]}
5 kx @end example
5 kx
5 kx @code{xargs} exits with the following status:
5 kx
5 kx @table @asis
5 kx @item 0
5 kx if it succeeds
5 kx @item 123
5 kx if any invocation of the command exited with status 1-125
5 kx @item 124
5 kx if the command exited with status 255
5 kx @item 125
5 kx if the command is killed by a signal
5 kx @item 126
5 kx if the command cannot be run
5 kx @item 127
5 kx if the command is not found
5 kx @item 1
5 kx if some other error occurred.
5 kx @end table
5 kx
5 kx Exit codes greater than 128 are used by the shell to indicate that
5 kx a program died due to a fatal signal.
5 kx
5 kx
5 kx @menu
5 kx * xargs options::
5 kx * Conflicting xargs options::
5 kx * Invoking the shell from xargs::
5 kx @end menu
5 kx
5 kx @node xargs options
5 kx @subsection xargs options
5 kx
5 kx @table @code
5 kx @item --arg-file@r{=@var{inputfile}}
5 kx @itemx -a @r{@var{inputfile}}
5 kx Read names from the file @var{inputfile} instead of standard input.
5 kx If you use this option, the standard input stream remains unchanged
5 kx when commands are run. Otherwise, stdin is redirected from
5 kx @file{/dev/null}.
5 kx
5 kx @item --null
5 kx @itemx -0
5 kx Input file names are terminated by a null character instead of by
5 kx whitespace, and any quotes and backslash characters are not considered
5 kx special (every character is taken literally). Disables the end of
5 kx file string, which is treated like any other argument.
5 kx
5 kx @item --delimiter @var{delim}
5 kx @itemx -d @var{delim}
5 kx
5 kx Input file names are terminated by the specified character @var{delim}
5 kx instead of by whitespace, and any quotes and backslash characters are
5 kx not considered special (every character is taken literally). Disables
5 kx the logical end of file marker string, which is treated like any other
5 kx argument.
5 kx
5 kx The specified delimiter may be a single character, a C-style character
5 kx escape such as @samp{\n}, or an octal or hexadecimal escape code.
5 kx Octal and hexadecimal escape codes are understood as for the
5 kx @code{printf} command. Multibyte characters are not supported.
5 kx
5 kx @item -E @var{eof-str}
5 kx @itemx --eof@r{[}=@var{eof-str}@r{]}
5 kx @itemx -e@r{[}@var{eof-str}@r{]}
5 kx
5 kx Set the logical end of file marker string to @var{eof-str}. If the
5 kx logical end of file marker string occurs as a line of input, the rest of
5 kx the input is ignored. If @var{eof-str} is omitted (@samp{-e}) or blank
5 kx (either @samp{-e} or @samp{-E}), there is no logical end of file marker
5 kx string. The @samp{-e} form of this option is deprecated in favour of
5 kx the POSIX-compliant @samp{-E} option, which you should use instead. As
5 kx of GNU @code{xargs} version 4.2.9, the default behaviour of @code{xargs}
5 kx is not to have a logical end of file marker string. The POSIX standard
5 kx (IEEE Std 1003.1, 2004 Edition) allows this.
5 kx
5 kx The logical end of file marker string is not treated specially if the
5 kx @samp{-d} or the @samp{-0} options are in effect. That is, when either
5 kx of these options are in effect, the whole input file will be read even
5 kx if @samp{-E} was used.
5 kx
5 kx @item --help
5 kx Print a summary of the options to @code{xargs} and exit.
5 kx
5 kx @item -I @var{replace-str}
5 kx @itemx --replace@r{[}=@var{replace-str}@r{]}
5 kx @itemx -i@r{[}@var{replace-str}@r{]}
5 kx Replace occurrences of @var{replace-str} in the initial arguments with
5 kx names read from standard input. Also, unquoted blanks do not
5 kx terminate arguments; instead, the input is split at newlines only. If
5 kx @var{replace-str} is omitted (omitting it is allowed only for
5 kx @samp{-i}), it defaults to @samp{@{@}} (like for @samp{find -exec}).
5 kx Implies @samp{-x} and @samp{-l 1}. The @samp{-i} option is deprecated
5 kx in favour of the @samp{-I} option.
5 kx
5 kx @item -L @var{max-lines}
5 kx @itemx --max-lines@r{[}=@var{max-lines}@r{]}
5 kx @itemx -l@r{[}@var{max-lines}@r{]}
5 kx Use at most @var{max-lines} non-blank input lines per command line.
5 kx For @samp{-l}, @var{max-lines} defaults to 1 if omitted. For
5 kx @samp{-L}, the argument is mandatory. Trailing blanks cause an input
5 kx line to be logically continued on the next input line, for the purpose
5 kx of counting the lines. Implies @samp{-x}. The @samp{-l} form of this
5 kx option is deprecated in favour of the POSIX-compliant @samp{-L}
5 kx option.
5 kx
5 kx @item --max-args=@var{max-args}
5 kx @itemx -n @var{max-args}
5 kx Use at most @var{max-args} arguments per command line. Fewer than
5 kx @var{max-args} arguments will be used if the size (see the @samp{-s}
5 kx option) is exceeded, unless the @samp{-x} option is given, in which
5 kx case @code{xargs} will exit.
5 kx
5 kx @item --open-tty
5 kx @itemx -o
5 kx Reopen stdin as @file{/dev/tty} in the child process before executing
5 kx the command, thus allowing that command to be associated to the terminal
5 kx while @code{xargs} reads from a different stream, e.g. from a pipe.
5 kx This is useful if you want @code{xargs} to run an interactive application.
5 kx @example
5 kx grep -lz PATTERN * | xargs -0o vi
5 kx @end example
5 kx
5 kx
5 kx @item --interactive
5 kx @itemx -p
5 kx Prompt the user about whether to run each command line and read a line
5 kx from the terminal. Only run the command line if the response starts
5 kx with @samp{y} or @samp{Y}. Implies @samp{-t}.
5 kx
5 kx @item --no-run-if-empty
5 kx @itemx -r
5 kx If the standard input is completely empty, do not run the
5 kx command. By default, the command is run once even if there is no
5 kx input.
5 kx
5 kx @item --max-chars=@var{max-chars}
5 kx @itemx -s @var{max-chars}
5 kx Use at most @var{max-chars} characters per command line, including the
5 kx command, initial arguments and any terminating nulls at the ends of
5 kx the argument strings.
5 kx
5 kx @item --show-limits
5 kx Display the limits on the command-line length which are imposed by the
5 kx operating system, @code{xargs}' choice of buffer size and the
5 kx @samp{-s} option. Pipe the input from @file{/dev/null} (and perhaps
5 kx specify @samp{--no-run-if-empty}) if you don't want @code{xargs} to do
5 kx anything.
5 kx
5 kx @item --verbose
5 kx @itemx -t
5 kx Print the command line on the standard error output before executing
5 kx it.
5 kx
5 kx @item --version
5 kx Print the version number of @code{xargs} and exit.
5 kx
5 kx @item --exit
5 kx @itemx -x
5 kx Exit if the size (see the @samp{-s} option) is exceeded.
5 kx
5 kx
5 kx @item --max-procs=@var{max-procs}
5 kx @itemx -P @var{max-procs}
5 kx Run simultaneously up to @var{max-procs} processes at once; the default is 1. If
5 kx @var{max-procs} is 0, @code{xargs} will run as many processes as
5 kx possible simultaneously. @xref{Controlling Parallelism}, for
5 kx information on dynamically controlling parallelism.
5 kx
5 kx @item --process-slot-var=@var{environment-variable-name}
5 kx Set the environment variable @var{environment-variable-name} to a
5 kx unique value in each running child process. Each value is a decimal
5 kx integer. Values are reused once child processes exit. This can be
5 kx used in a rudimentary load distribution scheme, for example.
5 kx @end table
5 kx
5 kx @node Conflicting xargs options
5 kx @subsection Conflicting options
5 kx The options @samp{--max-lines} (@samp{-L}, @samp{-l}), @samp{--replace}
5 kx (@samp{-I}, @samp{-i}) and @samp{--max-args} (@samp{-n}) are mutually exclusive.
5 kx
5 kx If some of them are specified at the same time, then @code{xargs} will
5 kx generally use the option specified last on the command line, i.e., it will
5 kx reset the value of the offending option (given before) to its default value.
5 kx Additionally, @code{xargs} will issue a warning diagnostic on @file{stderr}.
5 kx
5 kx @example
5 kx $ seq 4 | xargs -l2 -n3
5 kx xargs: warning: options --max-lines and --max-args/-n are \
5 kx mutually exclusive, ignoring previous --max-lines value
5 kx 1 2 3
5 kx 4
5 kx @end example
5 kx
5 kx The exception to this rule is that the special @var{max-args} value @var{1} is
5 kx ignored after the @samp{--replace} option and its short-option aliases @samp{-I}
5 kx and @samp{-i}, because it would not actually conflict.
5 kx @example
5 kx $ seq 2 | xargs --replace -n1 echo a-@{@}-b
5 kx a-1-b
5 kx a-2-b
5 kx @end example
5 kx
5 kx @node Invoking the shell from xargs
5 kx @subsection Invoking the shell from xargs
5 kx
5 kx Normally, @code{xargs} will exec the command you specified directly,
5 kx without invoking a shell. This is normally the behaviour one would
5 kx want. It's somewhat more efficient and avoids problems with shell
5 kx metacharacters, for example. However, sometimes it is necessary to
5 kx manipulate the environment of a command before it is run, in a way
5 kx that @code{xargs} does not directly support.
5 kx
5 kx Invoking a shell from @code{xargs} is a good way of performing such
5 kx manipulations. However, some care must be taken to prevent problems,
5 kx for example unwanted interpretation of shell metacharacters.
5 kx
5 kx This command moves a set of files into an archive directory:
5 kx
5 kx @example
5 kx find /foo -maxdepth 1 -atime +366 -exec mv @{@} /archive \;
5 kx @end example
5 kx
5 kx However, this will only move one file at a time. We cannot in this
5 kx case use @code{-exec ... +} because the matched file names are added
5 kx at the end of the command line, while the destination directory would
5 kx need to be specified last. We also can't use @code{xargs} in the
5 kx obvious way for the same reason. One way of working around this
5 kx problem is to make use of the special properties of GNU @code{mv}; it
5 kx has a @code{-t} option that allows specifying the target directory
5 kx before the list of files to be moved. However, while this
5 kx technique works for GNU @code{mv}, it doesn't solve the more general
5 kx problem.
5 kx
5 kx Here is a more general technique for solving this problem:
5 kx
5 kx @example
5 kx find /foo -maxdepth 1 -atime +366 -print0 |
5 kx xargs -r0 sh -c 'mv "$@@" /archive' move
5 kx @end example
5 kx
5 kx Here, a shell is being invoked. There are two shell instances to think
5 kx about. The first is the shell which launches the @code{xargs} command
5 kx (this might be the shell into which you are typing, for example). The
5 kx second is the shell launched by @code{xargs} (in fact it will probably
5 kx launch several, one after the other, depending on how many files need to
5 kx be archived). We'll refer to this second shell as a subshell.
5 kx
5 kx Our example uses the @code{-c} option of @code{sh}. Its argument is a
5 kx shell command to be executed by the subshell. Along with the rest of
5 kx that command, the $@@ is enclosed by single quotes to make sure it is
5 kx passed to the subshell without being expanded by the parent shell. It
5 kx is also enclosed with double quotes so that the subshell will expand
5 kx @code{$@@} correctly even if one of the file names contains a space or
5 kx newline.
5 kx
5 kx The subshell will use any non-option arguments as positional
5 kx parameters (that is, in the expansion of @code{$@@}). Because
5 kx @code{xargs} launches the @code{sh -c} subshell with a list of files,
5 kx those files will end up as the expansion of @code{$@@}.
5 kx
5 kx You may also notice the @samp{move} at the end of the command line.
5 kx This is used as the value of @code{$0} by the subshell. We include it
5 kx because otherwise the name of the first file to be moved would be used
5 kx instead. If that happened it would not be included in the subshell's
5 kx expansion of @code{$@@}, and so it wouldn't actually get moved.
5 kx
5 kx
5 kx Another reason to use the @code{sh -c} construct could be to
5 kx perform redirection:
5 kx
5 kx @example
5 kx find /usr/include -name '*.h' | xargs grep -wl mode_t |
5 kx xargs -r sh -c 'exec emacs "$@@" < /dev/tty' Emacs
5 kx @end example
5 kx
5 kx Notice that we use the shell builtin @code{exec} here. That's simply
5 kx because the subshell needs to do nothing once Emacs has been invoked.
5 kx Therefore instead of keeping a @code{sh} process around for no reason,
5 kx we just arrange for the subshell to exec Emacs, saving an extra
5 kx process creation.
5 kx
5 kx Although GNU @code{xargs} and the implementations on some other platforms
5 kx like BSD support the @samp{-o} option to achieve the same, the above is
5 kx the portable way to redirect stdin to @file{/dev/tty}.
5 kx
5 kx Sometimes, though, it can be helpful to keep the shell process around:
5 kx
5 kx @example
5 kx find /foo -maxdepth 1 -atime +366 -print0 |
5 kx xargs -r0 sh -c 'mv "$@@" /archive || exit 255' move
5 kx @end example
5 kx
5 kx Here, the shell will exit with status 255 if any @code{mv} failed.
5 kx This causes @code{xargs} to stop immediately.
5 kx
5 kx
5 kx @node Regular Expressions
5 kx @section Regular Expressions
5 kx
5 kx The @samp{-regex} and @samp{-iregex} tests of @code{find} allow
5 kx matching by regular expression, as does the @samp{--regex} option of
5 kx @code{locate}.
5 kx
5 kx Your locale configuration affects how regular expressions are
5 kx interpreted. @xref{Environment Variables}, for a description of how
5 kx your locale setup affects the interpretation of regular expressions.
5 kx
5 kx There are also several different types of regular expression, and
5 kx these are interpreted differently. Normally, the type of regular
5 kx expression used by @code{find} and @code{locate} is almost identical to
5 kx that used in GNU Emacs. The single difference is that in @code{find}
5 kx and @code{locate}, a @samp{.} will match a newline character.
5 kx
5 kx Both @code{find} and @code{locate} provide an option which allows
5 kx selecting an alternative regular expression syntax; for @code{find}
5 kx this is the @samp{-regextype} option, and for @code{locate} this is
5 kx the @samp{--regextype} option.
5 kx
5 kx These options take a single argument, which indicates the specific
5 kx regular expression syntax and behaviour that should be used. This
5 kx should be one of the following:
5 kx
5 kx @include regexprops.texi
5 kx
5 kx @node Environment Variables
5 kx @section Environment Variables
5 kx @c TODO: check the variable index still contains references to these
5 kx @table @code
5 kx @item LANG
5 kx Provides a default value for the internationalisation variables that
5 kx are unset or null.
5 kx
5 kx @item LC_ALL
5 kx If set to a non-empty string value, override the values of all the
5 kx other internationalisation variables.
5 kx
5 kx @item LC_COLLATE
5 kx The POSIX standard specifies that this variable affects the pattern
5 kx matching to be used for the `\-name' option. GNU find uses the
5 kx GNU version of the @code{fnmatch} library function.
5 kx
5 kx This variable also affects the interpretation of the response to
5 kx @code{-ok}; while the @code{LC_MESSAGES} variable selects the actual
5 kx pattern used to interpret the response to @code{-ok}, the interpretation
5 kx of any bracket expressions in the pattern will be affected by the
5 kx @code{LC_COLLATE} variable.
5 kx
5 kx @item LC_CTYPE
5 kx This variable affects the treatment of character classes used in
5 kx regular expression and with
5 kx the @samp{-name} test, if the @code{fnmatch} function supports this.
5 kx
5 kx This variable also affects the interpretation of any character classes
5 kx in the regular expressions used to interpret the response to the
5 kx prompt issued by @code{-ok}. The @code{LC_CTYPE} environment variable will
5 kx also affect which characters are considered to be unprintable when
5 kx filenames are printed (@pxref{Unusual Characters in File Names}).
5 kx
5 kx @item LC_MESSAGES
5 kx Determines the locale to be used for internationalised messages,
5 kx including the interpretation of the response to the prompt made by the
5 kx @code{-ok} action.
5 kx
5 kx @item NLSPATH
5 kx Determines the location of the internationalisation message catalogues.
5 kx
5 kx @item PATH
5 kx Affects the directories which are searched to find the executables
5 kx invoked by @samp{-exec}, @samp{-execdir} @samp{-ok} and @samp{-okdir}.
5 kx If the @var{PATH} environment variable includes the current directory
5 kx (by explicitly including @samp{.} or by having an empty element), and
5 kx the find command line includes @samp{-execdir} or @samp{-okdir},
5 kx @code{find} will refuse to run. @xref{Security Considerations}, for a
5 kx more detailed discussion of security matters.
5 kx
5 kx @item POSIXLY_CORRECT
5 kx Determines the block size used by @samp{-ls} and @samp{-fls}. If
5 kx @code{POSIXLY_CORRECT} is set, blocks are units of 512 bytes. Otherwise
5 kx they are units of 1024 bytes.
5 kx
5 kx Setting this variable also turns off warning messages (that is, implies
5 kx @samp{-nowarn}) by default, because POSIX requires that apart from
5 kx the output for @samp{-ok}, all messages printed on stderr are
5 kx diagnostics and must result in a non-zero exit status.
5 kx
5 kx When @code{POSIXLY_CORRECT} is set, the response to the prompt made by the
5 kx @code{-ok} action is interpreted according to the system's message
5 kx catalogue, as opposed to according to @code{find}'s own message
5 kx translations.
5 kx
5 kx @item TZ
5 kx Affects the time zone used for some of the time-related format
5 kx directives of @samp{-printf} and @samp{-fprintf}.
5 kx @end table
5 kx
5 kx
5 kx
5 kx @node Common Tasks
5 kx @chapter Common Tasks
5 kx
5 kx The sections that follow contain some extended examples that both give
5 kx a good idea of the power of these programs, and show you how to solve
5 kx common real-world problems.
5 kx
5 kx @menu
5 kx * Viewing And Editing::
5 kx * Archiving::
5 kx * Cleaning Up::
5 kx * Strange File Names::
5 kx * Fixing Permissions::
5 kx * Classifying Files::
5 kx @end menu
5 kx
5 kx @node Viewing And Editing
5 kx @section Viewing And Editing
5 kx
5 kx To view a list of files that meet certain criteria, simply run your
5 kx file viewing program with the file names as arguments. Shells
5 kx substitute a command enclosed in backquotes with its output, so the
5 kx whole command looks like this:
5 kx
5 kx @example
5 kx less `find /usr/include -name '*.h' | xargs grep -l mode_t`
5 kx @end example
5 kx
5 kx @noindent
5 kx You can edit those files by giving an editor name instead of a file
5 kx viewing program:
5 kx
5 kx @example
5 kx emacs `find /usr/include -name '*.h' | xargs grep -l mode_t`
5 kx @end example
5 kx
5 kx Because there is a limit to the length of any individual command line,
5 kx there is a limit to the number of files that can be handled in this way.
5 kx We can get around this difficulty by using @code{xargs} like this:
5 kx
5 kx @example
5 kx find /usr/include -name '*.h' | xargs grep -l mode_t > todo
5 kx xargs --arg-file=todo emacs
5 kx @end example
5 kx
5 kx Here, @code{xargs} will run @code{emacs} as many times as necessary to
5 kx visit all of the files listed in the file @file{todo}. Generating a
5 kx temporary file is not always convenient, though. This command does
5 kx much the same thing without needing one:
5 kx
5 kx @example
5 kx find /usr/include -name '*.h' | xargs grep -l mode_t |
5 kx xargs sh -c 'emacs "$@@" < /dev/tty' Emacs
5 kx @end example
5 kx
5 kx The example above illustrates a useful trick; Using @code{sh -c} you
5 kx can invoke a shell command from @code{xargs}. The @code{$@@} in the
5 kx command line is expanded by the shell to a list of arguments as
5 kx provided by @code{xargs}. The single quotes in the command line
5 kx protect the @code{$@@} against expansion by your interactive shell
5 kx (which will normally have no arguments and thus expand @code{$@@} to
5 kx nothing). The capitalised @samp{Emacs} on the command line is used as
5 kx @code{$0} by the shell that @code{xargs} launches.
5 kx
5 kx Please note that the implementations in GNU @code{xargs} and at least BSD
5 kx support the @samp{-o} option as extension to achieve the same, while the
5 kx above is the portable way to redirect stdin to @file{/dev/tty}.
5 kx
5 kx @node Archiving
5 kx @section Archiving
5 kx
5 kx You can pass a list of files produced by @code{find} to a file
5 kx archiving program. GNU @code{tar} and @code{cpio} can both read lists
5 kx of file names from the standard input -- either delimited by nulls (the
5 kx safe way) or by blanks (the lazy, risky default way). To use
5 kx null-delimited names, give them the @samp{--null} option. You can
5 kx store a file archive in a file, write it on a tape, or send it over a
5 kx network to extract on another machine.
5 kx
5 kx One common use of @code{find} to archive files is to send a list of
5 kx the files in a directory tree to @code{cpio}. Use @samp{-depth} so if
5 kx a directory does not have write permission for its owner, its contents
5 kx can still be restored from the archive since the directory's
5 kx permissions are restored after its contents. Here is an example of
5 kx doing this using @code{cpio}; you could use a more complex @code{find}
5 kx expression to archive only certain files.
5 kx
5 kx @example
5 kx find . -depth -print0 |
5 kx cpio --create --null --format=crc --file=/dev/nrst0
5 kx @end example
5 kx
5 kx You could restore that archive using this command:
5 kx
5 kx @example
5 kx cpio --extract --null --make-dir --unconditional \
5 kx --preserve --file=/dev/nrst0
5 kx @end example
5 kx
5 kx Here are the commands to do the same things using @code{tar}:
5 kx
5 kx @example
5 kx find . -depth -print0 |
5 kx tar --create --null --files-from=- --file=/dev/nrst0
5 kx
5 kx tar --extract --null --preserve-perm --same-owner \
5 kx --file=/dev/nrst0
5 kx @end example
5 kx
5 kx @c Idea from Rick Sladkey.
5 kx Here is an example of copying a directory from one machine to another:
5 kx
5 kx @example
5 kx find . -depth -print0 | cpio -0o -Hnewc |
5 kx rsh @var{other-machine} "cd `pwd` && cpio -i0dum"
5 kx @end example
5 kx
5 kx @node Cleaning Up
5 kx @section Cleaning Up
5 kx
5 kx @c Idea from Jim Meyering.
5 kx This section gives examples of removing unwanted files in various
5 kx situations. Here is a command to remove the CVS backup files created
5 kx when an update requires a merge:
5 kx
5 kx @example
5 kx find . -name '.#*' -print0 | xargs -0r rm -f
5 kx @end example
5 kx
5 kx If your @code{find} command removes directories, you may find that
5 kx you get a spurious error message when @code{find} tries to recurse
5 kx into a directory that has now been removed. Using the @samp{-depth}
5 kx option will normally resolve this problem.
5 kx
5 kx @c What does the following sentence mean? Why is -delete safer? --kasal
5 kx @c The command above works, but the following is safer:
5 kx
5 kx It is also possible to use the @samp{-delete} action:
5 kx
5 kx @example
5 kx find . -depth -name '.#*' -delete
5 kx @end example
5 kx
5 kx @c Idea from Franc,ois Pinard.
5 kx You can run this command to clean out your clutter in @file{/tmp}.
5 kx You might place it in the file your shell runs when you log out
5 kx (@file{.bash_logout}, @file{.logout}, or @file{.zlogout}, depending on
5 kx which shell you use).
5 kx
5 kx @example
5 kx find /tmp -depth -user "$LOGNAME" -type f -delete
5 kx @end example
5 kx
5 kx @c Idea from Noah Friedman.
5 kx To remove old Emacs backup and auto-save files, you can use a command
5 kx like the following. It is especially important in this case to use
5 kx null-terminated file names because Emacs packages like the VM mailer
5 kx often create temporary file names with spaces in them, like
5 kx @file{#reply to David J. MacKenzie<1>#}.
5 kx
5 kx @example
5 kx find ~ \( -name '*~' -o -name '#*#' \) -print0 |
5 kx xargs --no-run-if-empty --null rm -vf
5 kx @end example
5 kx
5 kx Removing old files from @file{/tmp} is commonly done from @code{cron}:
5 kx
5 kx @c Idea from Kaveh Ghazi.
5 kx @example
5 kx find /tmp /var/tmp -depth -not -type d -mtime +3 -delete
5 kx find /tmp /var/tmp -depth -mindepth 1 -type d -empty -delete
5 kx @end example
5 kx
5 kx The second @code{find} command above cleans out empty directories
5 kx depth-first (@samp{-delete} implies @samp{-depth} anyway), hoping that
5 kx the parents become empty and can be removed too. It uses
5 kx @samp{-mindepth} to avoid removing @file{/tmp} itself if it becomes
5 kx totally empty.
5 kx
5 kx
5 kx Lastly, an example of a program that almost certainly does not do what
5 kx the user intended:
5 kx
5 kx @c inspired by Savannah bug #20865 (Bruno De Fraine)
5 kx @example
5 kx find dirname -delete -name quux
5 kx @end example
5 kx
5 kx If the user hoped to delete only files named @file{quux} they will get
5 kx an unpleasant surprise; this command will attempt to delete everything
5 kx at or below the starting point @file{dirname}. This is because
5 kx @code{find} evaluates the items on the command line as an expression.
5 kx The @code{find} program will normally execute an action if the
5 kx preceding action succeeds. Here, there is no action or test before
5 kx the @samp{-delete} so it will always be executed. The @samp{-name
5 kx quux} test will be performed for files we successfully deleted, but
5 kx that test has no effect since @samp{-delete} also disables the default
5 kx @samp{-print} operation. So the above example will probably delete a
5 kx lot of files the user didn't want to delete.
5 kx
5 kx This command is also likely to do something you did not intend:
5 kx @example
5 kx find dirname -path dirname/foo -prune -o -delete
5 kx @end example
5 kx
5 kx Because @samp{-delete} turns on @samp{-depth}, the @samp{-prune}
5 kx action has no effect and files in @file{dirname/foo} will be deleted
5 kx too.
5 kx
5 kx
5 kx @node Strange File Names
5 kx @section Strange File Names
5 kx
5 kx @c Idea from:
5 kx @c From: tmatimar@isgtec.com (Ted Timar)
5 kx @c Newsgroups: comp.unix.questions,comp.unix.shell,comp.answers,news.answers
5 kx @c Subject: Unix - Frequently Asked Questions (2/7) [Frequent posting]
5 kx @c Subject: How do I remove a file with funny characters in the filename ?
5 kx @c Date: Thu Mar 18 17:16:55 EST 1993
5 kx @code{find} can help you remove or rename a file with strange
5 kx characters in its name. People are sometimes stymied by files whose
5 kx names contain characters such as spaces, tabs, control characters, or
5 kx characters with the high bit set. The simplest way to remove such
5 kx files is:
5 kx
5 kx @example
5 kx rm -i @var{some*pattern*that*matches*the*problem*file}
5 kx @end example
5 kx
5 kx @code{rm} asks you whether to remove each file matching the given
5 kx pattern. If you are using an old shell, this approach might not work
5 kx if the file name contains a character with the high bit set; the shell
5 kx may strip it off. A more reliable way is:
5 kx
5 kx @example
5 kx find . -maxdepth 1 @var{tests} -okdir rm '@{@}' \;
5 kx @end example
5 kx
5 kx @noindent
5 kx where @var{tests} uniquely identify the file. The @samp{-maxdepth 1}
5 kx option prevents @code{find} from wasting time searching for the file
5 kx in any subdirectories; if there are no subdirectories, you may omit
5 kx it. A good way to uniquely identify the problem file is to figure out
5 kx its inode number; use
5 kx
5 kx @example
5 kx ls -i
5 kx @end example
5 kx
5 kx Suppose you have a file whose name contains control characters, and
5 kx you have found that its inode number is 12345. This command prompts
5 kx you for whether to remove it:
5 kx
5 kx @example
5 kx find . -maxdepth 1 -inum 12345 -okdir rm -f '@{@}' \;
5 kx @end example
5 kx
5 kx If you don't want to be asked, perhaps because the file name may
5 kx contain a strange character sequence that will mess up your screen
5 kx when printed, then use @samp{-execdir} instead of @samp{-okdir}.
5 kx
5 kx If you want to rename the file instead, you can use @code{mv} instead
5 kx of @code{rm}:
5 kx
5 kx @example
5 kx find . -maxdepth 1 -inum 12345 -okdir mv '@{@}' @var{new-file-name} \;
5 kx @end example
5 kx
5 kx @node Fixing Permissions
5 kx @section Fixing Permissions
5 kx
5 kx Suppose you want to make sure that everyone can write to the
5 kx directories in a certain directory tree. Here is a way to find
5 kx directories lacking either user or group write permission (or both),
5 kx and fix their permissions:
5 kx
5 kx @example
5 kx find . -type d -not -perm -ug=w | xargs chmod ug+w
5 kx @end example
5 kx
5 kx @noindent
5 kx You could also reverse the operations, if you want to make sure that
5 kx directories do @emph{not} have world write permission.
5 kx
5 kx @node Classifying Files
5 kx @section Classifying Files
5 kx
5 kx @c Idea from:
5 kx @c From: martin@mwtech.UUCP (Martin Weitzel)
5 kx @c Newsgroups: comp.unix.wizards,comp.unix.questions
5 kx @c Subject: Advanced usage of 'find' (Re: Unix security automating script)
5 kx @c Date: 22 Mar 90 15:05:19 GMT
5 kx If you want to classify a set of files into several groups based on
5 kx different criteria, you can use the comma operator to perform multiple
5 kx independent tests on the files. Here is an example:
5 kx
5 kx @example
5 kx find / -type d \( -perm -o=w -fprint allwrite , \
5 kx -perm -o=x -fprint allexec \)
5 kx
5 kx echo "Directories that can be written to by everyone:"
5 kx cat allwrite
5 kx echo ""
5 kx echo "Directories with search permissions for everyone:"
5 kx cat allexec
5 kx @end example
5 kx
5 kx @code{find} has only to make one scan through the directory tree
5 kx (which is one of the most time consuming parts of its work).
5 kx
5 kx @node Worked Examples
5 kx @chapter Worked Examples
5 kx
5 kx The tools in the findutils package, and in particular @code{find},
5 kx have a large number of options. This means that quite often,
5 kx there is more than one way to do things. Some of the options
5 kx and facilities only exist for compatibility with other tools, and
5 kx findutils provides improved ways of doing things.
5 kx
5 kx This chapter describes a number of useful tasks that are commonly
5 kx performed, and compares the different ways of achieving them.
5 kx
5 kx @menu
5 kx * Deleting Files::
5 kx * Copying A Subset of Files::
5 kx * Updating A Timestamp File::
5 kx * Finding the Shallowest Instance::
5 kx @end menu
5 kx
5 kx @node Deleting Files
5 kx @section Deleting Files
5 kx
5 kx One of the most common tasks that @code{find} is used for is locating
5 kx files that can be deleted. This might include:
5 kx
5 kx @itemize
5 kx @item
5 kx Files last modified more than 3 years ago which haven't been accessed
5 kx for at least 2 years
5 kx @item
5 kx Files belonging to a certain user
5 kx @item
5 kx Temporary files which are no longer required
5 kx @end itemize
5 kx
5 kx This example concentrates on the actual deletion task rather than on
5 kx sophisticated ways of locating the files that need to be deleted.
5 kx We'll assume that the files we want to delete are old files underneath
5 kx @file{/var/tmp/stuff}.
5 kx
5 kx @subsection The Traditional Way
5 kx
5 kx The traditional way to delete files in @file{/var/tmp/stuff} that have
5 kx not been modified in over 90 days would have been:
5 kx
5 kx @smallexample
5 kx find /var/tmp/stuff -mtime +90 -exec /bin/rm @{@} \;
5 kx @end smallexample
5 kx
5 kx The above command uses @samp{-exec} to run the @code{/bin/rm} command
5 kx to remove each file. This approach works and in fact would have
5 kx worked in Version 7 Unix in 1979. However, there are a number of
5 kx problems with this approach.
5 kx
5 kx
5 kx The most obvious problem with the approach above is that it causes
5 kx @code{find} to fork every time it finds a file that needs to delete,
5 kx and the child process then has to use the @code{exec} system call to
5 kx launch @code{/bin/rm}. All this is quite inefficient. If we are
5 kx going to use @code{/bin/rm} to do this job, it is better to make it
5 kx delete more than one file at a time.
5 kx
5 kx The most obvious way of doing this is to use the shell's command
5 kx expansion feature:
5 kx
5 kx @smallexample
5 kx /bin/rm `find /var/tmp/stuff -mtime +90 -print`
5 kx @end smallexample
5 kx or you could use the more modern form
5 kx @smallexample
5 kx /bin/rm $(find /var/tmp/stuff -mtime +90 -print)
5 kx @end smallexample
5 kx
5 kx The commands above are much more efficient than the first attempt.
5 kx However, there is a problem with them. The shell has a maximum
5 kx command length which is imposed by the operating system (the actual
5 kx limit varies between systems). This means that while the command
5 kx expansion technique will usually work, it will suddenly fail when
5 kx there are lots of files to delete. Since the task is to delete
5 kx unwanted files, this is precisely the time we don't want things to go
5 kx wrong.
5 kx
5 kx @subsection Making Use of @code{xargs}
5 kx
5 kx So, is there a way to be more efficient in the use of @code{fork()}
5 kx and @code{exec()} without running up against this limit?
5 kx Yes, we can be almost optimally efficient by making use
5 kx of the @code{xargs} command. The @code{xargs} command reads arguments
5 kx from its standard input and builds them into command lines. We can
5 kx use it like this:
5 kx
5 kx @smallexample
5 kx find /var/tmp/stuff -mtime +90 -print | xargs /bin/rm
5 kx @end smallexample
5 kx
5 kx For example if the files found by @code{find} are
5 kx @file{/var/tmp/stuff/A},
5 kx @file{/var/tmp/stuff/B} and
5 kx @file{/var/tmp/stuff/C} then @code{xargs} might issue the commands
5 kx
5 kx @smallexample
5 kx /bin/rm /var/tmp/stuff/A /var/tmp/stuff/B
5 kx /bin/rm /var/tmp/stuff/C
5 kx @end smallexample
5 kx
5 kx The above assumes that @code{xargs} has a very small maximum command
5 kx line length. The real limit is much larger but the idea is that
5 kx @code{xargs} will run @code{/bin/rm} as many times as necessary to get
5 kx the job done, given the limits on command line length.
5 kx
5 kx This usage of @code{xargs} is pretty efficient, and the @code{xargs}
5 kx command is widely implemented (all modern versions of Unix offer it).
5 kx So far then, the news is all good. However, there is bad news too.
5 kx
5 kx @subsection Unusual characters in filenames
5 kx
5 kx Unix-like systems allow any characters to appear in file names with
5 kx the exception of the ASCII NUL character and the slash.
5 kx Slashes can occur in path names (as the directory separator) but
5 kx not in the names of actual directory entries. This means that the
5 kx list of files that @code{xargs} reads could in fact contain white space
5 kx characters -- spaces, tabs and newline characters. Since by default,
5 kx @code{xargs} assumes that the list of files it is reading uses white
5 kx space as an argument separator, it cannot correctly handle the case
5 kx where a filename actually includes white space. This makes the
5 kx default behaviour of @code{xargs} almost useless for handling
5 kx arbitrary data.
5 kx
5 kx To solve this problem, GNU findutils introduced the @samp{-print0}
5 kx action for @code{find}. This uses the ASCII NUL character to separate
5 kx the entries in the file list that it produces. This is the ideal
5 kx choice of separator since it is the only character that cannot appear
5 kx within a path name. The @samp{-0} option to @code{xargs} makes it
5 kx assume that arguments are separated with ASCII NUL instead of white
5 kx space. It also turns off another misfeature in the default behaviour
5 kx of @code{xargs}, which is that it pays attention to quote characters
5 kx in its input. Some versions of @code{xargs} also terminate when they
5 kx see a lone @samp{_} in the input, but GNU @code{find} no longer does
5 kx that (since it has become an optional behaviour in the Unix standard).
5 kx
5 kx So, putting @code{find -print0} together with @code{xargs -0} we get
5 kx this command:
5 kx
5 kx @smallexample
5 kx find /var/tmp/stuff -mtime +90 -print0 | xargs -0 /bin/rm
5 kx @end smallexample
5 kx
5 kx The result is an efficient way of proceeding that
5 kx correctly handles all the possible characters that could appear in the
5 kx list of files to delete. This is good news. However, there is, as
5 kx I'm sure you're expecting, also more bad news. The problem is that
5 kx this is not a portable construct; although other versions of Unix
5 kx (notably BSD-derived ones) support @samp{-print0}, it's not
5 kx universal. So, is there a more universal mechanism?
5 kx
5 kx @subsection Going back to @code{-exec}
5 kx
5 kx There is indeed a more universal mechanism, which is a slight
5 kx modification to the @samp{-exec} action. The normal @samp{-exec}
5 kx action assumes that the command to run is terminated with a semicolon
5 kx (the semicolon normally has to be quoted in order to protect it from
5 kx interpretation as the shell command separator). The SVR4 edition of
5 kx Unix introduced a slight variation, which involves terminating the
5 kx command with @samp{+} instead:
5 kx
5 kx @smallexample
5 kx find /var/tmp/stuff -mtime +90 -exec /bin/rm @{@} \+
5 kx @end smallexample
5 kx
5 kx The above use of @samp{-exec} causes @code{find} to build up a long
5 kx command line and then issue it. This can be less efficient than some
5 kx uses of @code{xargs}; for example @code{xargs} allows building up
5 kx new command lines while the previous command is still executing, and
5 kx allows specifying a number of commands to run in parallel.
5 kx However, the @code{find @dots{} -exec @dots{} +} construct has the advantage
5 kx of wide portability. GNU findutils did not support @samp{-exec @dots{} +}
5 kx until version 4.2.12; one of the reasons for this is that it already
5 kx had the @samp{-print0} action in any case.
5 kx
5 kx
5 kx @subsection A more secure version of @code{-exec}
5 kx
5 kx The command above seems to be efficient and portable. However,
5 kx within it lurks a security problem. The problem is shared with
5 kx all the commands we've tried in this worked example so far, too. The
5 kx security problem is a race condition; that is, if it is possible for
5 kx somebody to manipulate the filesystem that you are searching while you
5 kx are searching it, it is possible for them to persuade your @code{find}
5 kx command to cause the deletion of a file that you can delete but they
5 kx normally cannot.
5 kx
5 kx The problem occurs because the @samp{-exec} action is defined by the
5 kx POSIX standard to invoke its command with the same working directory
5 kx as @code{find} had when it was started. This means that the arguments
5 kx which replace the @{@} include a relative path from @code{find}'s
5 kx starting point down the file that needs to be deleted. For example,
5 kx
5 kx @smallexample
5 kx find /var/tmp/stuff -mtime +90 -exec /bin/rm @{@} \+
5 kx @end smallexample
5 kx
5 kx might actually issue the command:
5 kx
5 kx @smallexample
5 kx /bin/rm /var/tmp/stuff/A /var/tmp/stuff/B /var/tmp/stuff/passwd
5 kx @end smallexample
5 kx
5 kx Notice the file @file{/var/tmp/stuff/passwd}. Likewise, the command:
5 kx
5 kx @smallexample
5 kx cd /var/tmp && find stuff -mtime +90 -exec /bin/rm @{@} \+
5 kx @end smallexample
5 kx
5 kx might actually issue the command:
5 kx
5 kx @smallexample
5 kx /bin/rm stuff/A stuff/B stuff/passwd
5 kx @end smallexample
5 kx
5 kx If an attacker can rename @file{stuff} to something else (making use
5 kx of their write permissions in @file{/var/tmp}) they can replace it
5 kx with a symbolic link to @file{/etc}. That means that the
5 kx @code{/bin/rm} command will be invoked on @file{/etc/passwd}. If you
5 kx are running your @code{find} command as root, the attacker has just managed
5 kx to delete a vital file. All they needed to do to achieve this was
5 kx replace a subdirectory with a symbolic link at the vital moment.
5 kx
5 kx There is however, a simple solution to the problem. This is an action
5 kx which works a lot like @code{-exec} but doesn't need to traverse a
5 kx chain of directories to reach the file that it needs to work on. This
5 kx is the @samp{-execdir} action, which was introduced by the BSD family
5 kx of operating systems. The command,
5 kx
5 kx @smallexample
5 kx find /var/tmp/stuff -mtime +90 -execdir /bin/rm @{@} \+
5 kx @end smallexample
5 kx
5 kx might delete a set of files by performing these actions:
5 kx
5 kx @enumerate
5 kx @item
5 kx Change directory to /var/tmp/stuff/foo
5 kx @item
5 kx Invoke @code{/bin/rm ./file1 ./file2 ./file3}
5 kx @item
5 kx Change directory to /var/tmp/stuff/bar
5 kx @item
5 kx Invoke @code{/bin/rm ./file99 ./file100 ./file101}
5 kx @end enumerate
5 kx
5 kx This is a much more secure method. We are no longer exposed to a race
5 kx condition. For many typical uses of @code{find}, this is the best
5 kx strategy. It's reasonably efficient, but the length of the command
5 kx line is limited not just by the operating system limits, but also by
5 kx how many files we actually need to delete from each directory.
5 kx
5 kx Is it possible to do any better? In the case of general file
5 kx processing, no. However, in the specific case of deleting files it is
5 kx indeed possible to do better.
5 kx
5 kx @subsection Using the @code{-delete} action
5 kx
5 kx The most efficient and secure method of solving this problem is to use
5 kx the @samp{-delete} action:
5 kx
5 kx @smallexample
5 kx find /var/tmp/stuff -mtime +90 -delete
5 kx @end smallexample
5 kx
5 kx This alternative is more efficient than any of the @samp{-exec} or
5 kx @samp{-execdir} actions, since it entirely avoids the overhead of
5 kx forking a new process and using @code{exec} to run @code{/bin/rm}. It
5 kx is also normally more efficient than @code{xargs} for the same
5 kx reason. The file deletion is performed from the directory containing
5 kx the entry to be deleted, so the @samp{-delete} action has the same
5 kx security advantages as the @samp{-execdir} action has.
5 kx
5 kx The @samp{-delete} action was introduced by the BSD family of
5 kx operating systems.
5 kx
5 kx @subsection Improving things still further
5 kx
5 kx Is it possible to improve things still further? Not without either
5 kx modifying the system library to the operating system or having more specific
5 kx knowledge of the layout of the filesystem and disk I/O subsystem, or
5 kx both.
5 kx
5 kx The @code{find} command traverses the filesystem, reading
5 kx directories. It then issues a separate system call for each file to
5 kx be deleted. If we could modify the operating system, there are
5 kx potential gains that could be made:
5 kx
5 kx @itemize
5 kx @item
5 kx We could have a system call to which we pass more than one filename
5 kx for deletion
5 kx @item
5 kx Alternatively, we could pass in a list of inode numbers (on GNU/Linux
5 kx systems, @code{readdir()} also returns the inode number of each
5 kx directory entry) to be deleted.
5 kx @end itemize
5 kx
5 kx The above possibilities sound interesting, but from the kernel's point
5 kx of view it is difficult to enforce standard Unix access controls for
5 kx such processing by inode number. Such a facility would probably
5 kx need to be restricted to the superuser.
5 kx
5 kx Another way of improving performance would be to increase the
5 kx parallelism of the process. For example if the directory hierarchy we
5 kx are searching is actually spread across a number of disks, we might
5 kx somehow be able to arrange for @code{find} to process each disk in
5 kx parallel. In practice GNU @code{find} doesn't have such an intimate
5 kx understanding of the system's filesystem layout and disk I/O
5 kx subsystem.
5 kx
5 kx However, since the system administrator can have such an understanding
5 kx they can take advantage of it like so:
5 kx
5 kx @smallexample
5 kx find /var/tmp/stuff1 -mtime +90 -delete &
5 kx find /var/tmp/stuff2 -mtime +90 -delete &
5 kx find /var/tmp/stuff3 -mtime +90 -delete &
5 kx find /var/tmp/stuff4 -mtime +90 -delete &
5 kx wait
5 kx @end smallexample
5 kx
5 kx In the example above, four separate instances of @code{find} are used
5 kx to search four subdirectories in parallel. The @code{wait} command
5 kx simply waits for all of these to complete. Whether this approach is
5 kx more or less efficient than a single instance of @code{find} depends
5 kx on a number of things:
5 kx
5 kx @itemize
5 kx @item
5 kx Are the directories being searched in parallel actually on separate
5 kx disks? If not, this parallel search might just result in a lot of
5 kx disk head movement and so the speed might even be slower.
5 kx @item
5 kx Other activity - are other programs also doing things on those disks?
5 kx @end itemize
5 kx
5 kx
5 kx @subsection Conclusion
5 kx
5 kx The fastest and most secure way to delete files with the help of
5 kx @code{find} is to use @samp{-delete}. Using @code{xargs -0 -P N} can
5 kx also make effective use of the disk, but it is not as secure.
5 kx
5 kx In the case where we're doing things other than deleting files, the
5 kx most secure alternative is @samp{-execdir @dots{} +}, but this is not as
5 kx portable as the insecure action @samp{-exec @dots{} +}.
5 kx
5 kx The @samp{-delete} action is not completely portable, but the only
5 kx other possibility which is as secure (@samp{-execdir}) is no more
5 kx portable. The most efficient portable alternative is @samp{-exec
5 kx @dots{}+}, but this is insecure and isn't supported by versions of GNU
5 kx findutils prior to 4.2.12.
5 kx
5 kx @node Copying A Subset of Files
5 kx @section Copying A Subset of Files
5 kx
5 kx Suppose you want to copy some files from @file{/source-dir} to
5 kx @file{/dest-dir}, but there are a small number of files in
5 kx @file{/source-dir} you don't want to copy.
5 kx
5 kx One option of course is @code{cp /source-dir /dest-dir} followed by
5 kx deletion of the unwanted material under @file{/dest-dir}. But often
5 kx that can be inconvenient, because for example we would have copied a
5 kx large amount of extraneous material, or because @file{/dest-dir} is
5 kx too small. Naturally there are many other possible reasons why this
5 kx strategy may be unsuitable.
5 kx
5 kx So we need to have some way of identifying which files we want to
5 kx copy, and we need to have a way of copying that file list. The second
5 kx part of this condition is met by @code{cpio -p}. Of course, we can
5 kx identify the files we wish to copy by using @code{find}. Here is a
5 kx command that solves our problem:
5 kx
5 kx @example
5 kx cd /source-dir
5 kx find . -name '.snapshot' -prune -o \( \! -name '*~' -print0 \) |
5 kx cpio -pmd0 /dest-dir
5 kx @end example
5 kx
5 kx The first part of the @code{find} command here identifies files or
5 kx directories named @file{.snapshot} and tells @code{find} not to
5 kx recurse into them (since they do not need to be copied). The
5 kx combination @code{-name '.snapshot' -prune} yields false for anything
5 kx that didn't get pruned, but it is exactly those files we want to
5 kx copy. Therefore we need to use an OR (@samp{-o}) condition to
5 kx introduce the rest of our expression. The remainder of the expression
5 kx simply arranges for the name of any file not ending in @samp{~} to be
5 kx printed.
5 kx
5 kx Using @code{-print0} ensures that white space characters in file names
5 kx do not pose a problem. The @code{cpio} command does the actual work
5 kx of copying files. The program as a whole fails if the @code{cpio}
5 kx program returns nonzero. If the @code{find} command returns non-zero
5 kx on the other hand, the Unix shell will not diagnose a problem (since
5 kx @code{find} is not the last command in the pipeline).
5 kx
5 kx
5 kx @node Updating A Timestamp File
5 kx @section Updating A Timestamp File
5 kx
5 kx Suppose we have a directory full of files which is maintained with a
5 kx set of automated tools; perhaps one set of tools updates them and
5 kx another set of tools uses the result. In this situation, it might be
5 kx useful for the second set of tools to know if the files have recently
5 kx been changed. It might be useful, for example, to have a 'timestamp'
5 kx file which gives the timestamp on the newest file in the collection.
5 kx
5 kx We can use @code{find} to achieve this, but there are several
5 kx different ways to do it.
5 kx
5 kx @subsection Updating the Timestamp The Wrong Way
5 kx
5 kx The obvious but wrong answer is just to use @samp{-newer}:
5 kx
5 kx @smallexample
5 kx find subdir -newer timestamp -exec touch -r @{@} timestamp \;
5 kx @end smallexample
5 kx
5 kx This does the right sort of thing but has a bug. Suppose that two
5 kx files in the subdirectory have been updated, and that these are called
5 kx @file{file1} and @file{file2}. The command above will update
5 kx @file{timestamp} with the modification time of @file{file1} or that of
5 kx @file{file2}, but we don't know which one. Since the timestamps on
5 kx @file{file1} and @file{file2} will in general be different, this could
5 kx well be the wrong value.
5 kx
5 kx One solution to this problem is to modify @code{find} to recheck the
5 kx modification time of @file{timestamp} every time a file is to be
5 kx compared against it, but that will reduce the performance of
5 kx @code{find}.
5 kx
5 kx @subsection Using the test utility to compare timestamps
5 kx
5 kx The @code{test} command can be used to compare timestamps:
5 kx
5 kx @smallexample
5 kx find subdir -exec test @{@} -nt timestamp \; -exec touch -r @{@} timestamp \;
5 kx @end smallexample
5 kx
5 kx This will ensure that any changes made to the modification time of
5 kx @file{timestamp} that take place during the execution of @code{find}
5 kx are taken into account. This resolves our earlier problem, but
5 kx unfortunately this runs much more slowly.
5 kx
5 kx @subsection A combined approach
5 kx
5 kx We can of course still use @samp{-newer} to cut down on the number of
5 kx calls to @code{test}:
5 kx
5 kx @smallexample
5 kx find subdir -newer timestamp -and \
5 kx -exec test @{@} -nt timestamp \; -and \
5 kx -exec touch -r @{@} timestamp \;
5 kx @end smallexample
5 kx
5 kx Here, the @samp{-newer} test excludes all the files which are
5 kx definitely older than the timestamp, but all the files which are newer
5 kx than the old value of the timestamp are compared against the current
5 kx updated timestamp.
5 kx
5 kx This is indeed faster in general, but the speed difference will depend
5 kx on how many updated files there are.
5 kx
5 kx @subsection Using @code{-printf} and @code{sort} to compare timestamps
5 kx
5 kx It is possible to use the @samp{-printf} action to abandon the use of
5 kx @code{test} entirely:
5 kx
5 kx @smallexample
5 kx newest=$(find subdir -newer timestamp -printf "%A@:%p\n" |
5 kx sort -n |
5 kx tail -n1 |
5 kx cut -d: -f2- )
5 kx touch -r "$@{newest:-timestamp@}" timestamp
5 kx @end smallexample
5 kx
5 kx The command above works by generating a list of the timestamps and
5 kx names of all the files which are newer than the timestamp. The
5 kx @code{sort}, @code{tail} and @code{cut} commands simply pull out the
5 kx name of the file with the largest timestamp value (that is, the latest
5 kx file). The @code{touch} command is then used to update the timestamp,
5 kx
5 kx The @code{"$@{newest:-timestamp@}"} expression simply expands to the
5 kx value of @code{$newest} if that variable is set, but to
5 kx @file{timestamp} otherwise. This ensures that an argument is always
5 kx given to the @samp{-r} option of the @code{touch} command.
5 kx
5 kx This approach seems quite efficient, but unfortunately it has a
5 kx problem. Many operating systems now keep file modification time
5 kx information at a granularity which is finer than one second.
5 kx Findutils version 4.3.3 and later will print a fractional part with
5 kx %A@@, but older versions will not.
5 kx
5 kx
5 kx @subsection Solving the problem with @code{make}
5 kx
5 kx Another tool which often works with timestamps is @code{make}. We can
5 kx use @code{find} to generate a @file{Makefile} file on the fly and then
5 kx use @code{make} to update the timestamps:
5 kx
5 kx @smallexample
5 kx makefile=$(mktemp)
5 kx find subdir \
5 kx \( \! -xtype l \) \
5 kx -newer timestamp \
5 kx -printf "timestamp:: %p\n\ttouch -r %p timestamp\n\n" > "$makefile"
5 kx make -f "$makefile"
5 kx rm -f "$makefile"
5 kx @end smallexample
5 kx
5 kx Unfortunately although the solution above is quite elegant, it fails
5 kx to cope with white space within file names, and adjusting it to do so
5 kx would require a rather complex shell script.
5 kx
5 kx
5 kx @subsection Coping with odd filenames too
5 kx
5 kx We can fix both of these problems (looping and problems with white
5 kx space), and do things more efficiently too. The following command
5 kx works with newlines and doesn't need to sort the list of filenames.
5 kx
5 kx @smallexample
5 kx find subdir -newer timestamp -printf "%A@@:%p\0" |
5 kx perl -0 newest.pl |
5 kx xargs --no-run-if-empty --null -i \
5 kx find @{@} -maxdepth 0 -newer timestamp -exec touch -r @{@} timestamp \;
5 kx @end smallexample
5 kx
5 kx The first @code{find} command generates a list of files which are
5 kx newer than the original timestamp file, and prints a list of them with
5 kx their timestamps. The @file{newest.pl} script simply filters out all
5 kx the filenames which have timestamps which are older than whatever the
5 kx newest file is:
5 kx
5 kx @smallexample
5 kx @verbatim
5 kx #! /usr/bin/perl -0
5 kx my @newest = ();
5 kx my $latest_stamp = undef;
5 kx while (<>) {
5 kx my ($stamp, $name) = split(/:/);
5 kx if (!defined($latest_stamp) || ($tstamp > $latest_stamp)) {
5 kx $latest_stamp = $stamp;
5 kx @newest = ();
5 kx }
5 kx if ($tstamp >= $latest_stamp) {
5 kx push @newest, $name;
5 kx }
5 kx }
5 kx print join("\0", @newest);
5 kx @end verbatim
5 kx @end smallexample
5 kx
5 kx This prints a list of zero or more files, all of which are newer than
5 kx the original timestamp file, and which have the same timestamp as each
5 kx other, to the nearest second. The second @code{find} command takes
5 kx each resulting file one at a time, and if that is newer than the
5 kx timestamp file, the timestamp is updated.
5 kx
5 kx @node Finding the Shallowest Instance
5 kx @section Finding the Shallowest Instance
5 kx
5 kx Suppose you maintain local copies of sources from various projects,
5 kx each with their own choice of directory organisation and source code
5 kx management (SCM) tool. You need to periodically synchronize each
5 kx project with its upstream tree. As the number local repositories
5 kx grows, so does the work involved in maintaining synchronization. SCM
5 kx utilities typically create some sort of administrative directory: .svn
5 kx for Subversion, CVS for CVS, and so on. These directories can be used
5 kx as a key to search for the bases of the project source trees. Suppose
5 kx we have the following directory structure:
5 kx
5 kx @smallexample
5 kx repo/project1/CVS
5 kx repo/gnu/project2/.svn
5 kx repo/gnu/project3/.svn
5 kx repo/gnu/project3/src/.svn
5 kx repo/gnu/project3/doc/.svn
5 kx repo/project4/.git
5 kx @end smallexample
5 kx
5 kx One would expect to update each of the @file{projectX} directories,
5 kx but not their subdirectories (src, doc, etc.). To locate the project
5 kx roots, we would need to find the least deeply nested directories
5 kx containing an SCM-related subdirectory. The following command
5 kx discovers those roots efficiently. It is efficient because it avoids
5 kx searching subdirectories inside projects whose SCM directory we
5 kx already found.
5 kx
5 kx @smallexample
5 kx find repo/ \
5 kx -exec test -d @{@}/.svn \; -or \
5 kx -exec test -d @{@}/.git \; -or \
5 kx -exec test -d @{@}/CVS \; -print -prune
5 kx @end smallexample
5 kx
5 kx In this example, @command{test} is used to tell if we are currently
5 kx examining a directory which appears to the a project's root directory
5 kx (because it has an SCM subdirectory). When we find a project root,
5 kx there is no need to search inside it, and @code{-prune} makes sure
5 kx that we descend no further.
5 kx
5 kx For large, complex trees like the Linux kernel, this will prevent
5 kx searching a large portion of the structure, saving a good deal of
5 kx time.
5 kx
5 kx
5 kx @node Security Considerations
5 kx @chapter Security Considerations
5 kx
5 kx Security considerations are important if you are using @code{find} or
5 kx @code{xargs} to search for or process files that don't belong to you
5 kx or which other people have control. Security considerations
5 kx relating to @code{locate} may also apply if you have files which you
5 kx do not want others to see.
5 kx
5 kx The most severe forms of security problems affecting
5 kx @code{find} and related programs are when third parties bring
5 kx about a situation allowing them to do something
5 kx they would normally not be able to accomplish. This is called @emph{privilege
5 kx elevation}. This might include deleting files they would not normally
5 kx be able to delete. It is common for the operating system to periodically
5 kx invoke @code{find} for self-maintenance purposes. These invocations of
5 kx @code{find} are particularly problematic from a security point of view
5 kx as these are often invoked by the superuser and search the entire
5 kx filesystem hierarchy. Generally, the severity of any associated problem depends
5 kx on what the system is going to do with the files found by @code{find}.
5 kx
5 kx @menu
5 kx * Levels of Risk:: What is your level of exposure to security problems?
5 kx * Security Considerations for find:: Security problems with find
5 kx * Security Considerations for xargs:: Security problems with xargs
5 kx * Security Considerations for locate:: Security problems with locate
5 kx * Security Summary:: That was all very complex, what does it boil down to?
5 kx * Further Reading on Security::
5 kx @end menu
5 kx
5 kx
5 kx @node Levels of Risk
5 kx @section Levels of Risk
5 kx
5 kx There are some security risks inherent in the use of @code{find},
5 kx @code{xargs} and (to a lesser extent) @code{locate}. The severity of
5 kx these risks depends on what sort of system you are using:
5 kx
5 kx @table @strong
5 kx @item High risk
5 kx Multi-user systems where you do not control (or trust) the other
5 kx users, and on which you execute @code{find}, including areas where
5 kx those other users can manipulate the filesystem (for example beneath
5 kx @file{/home} or @file{/tmp}).
5 kx
5 kx @item Medium Risk
5 kx Systems where the actions of other users can create file names chosen
5 kx by them, but to which they don't have access while @code{find} is
5 kx being run. This access might include leaving programs running (shell
5 kx background jobs, @code{at} or @code{cron} tasks, for example). On
5 kx these sorts of systems, carefully written commands (avoiding use of
5 kx @samp{-print} for example) should not expose you to a high degree of
5 kx risk. Most systems fall into this category.
5 kx
5 kx @item Low Risk
5 kx Systems to which untrusted parties do not have access, cannot create
5 kx file names of their own choice (even remotely) and which contain no
5 kx security flaws which might enable an untrusted third party to gain
5 kx access. Most systems do not fall into this category because there are
5 kx many ways in which external parties can affect the names of files that
5 kx are created on your system. The system on which I am writing this for
5 kx example automatically downloads software updates from the Internet;
5 kx the names of the files in which these updates exist are chosen by
5 kx third parties@footnote{Of course, I trust these parties to a large
5 kx extent anyway, because I install software provided by them; I choose
5 kx to trust them in this way, and that's a deliberate choice}.
5 kx @end table
5 kx
5 kx In the discussion above, ``risk'' denotes the likelihood that someone
5 kx can cause @code{find}, @code{xargs}, @code{locate} or some other
5 kx program which is controlled by them to do something you did not
5 kx intend. The levels of risk suggested do not take any account of the
5 kx consequences of this sort of event. That is, if you operate a ``low
5 kx risk'' type system, but the consequences of a security problem are
5 kx disastrous, then you should still give serious thought to all the
5 kx possible security problems, many of which of course will not be
5 kx discussed here -- this section of the manual is intended to be
5 kx informative but not comprehensive or exhaustive.
5 kx
5 kx If you are responsible for the operation of a system where the
5 kx consequences of a security problem could be very important, you should
5 kx do two things:
5 kx
5 kx @enumerate
5 kx @item Define a security policy which defines who is allowed to do what
5 kx on your system.
5 kx @item Seek competent advice on how to enforce your policy, detect
5 kx breaches of that policy, and take account of any potential problems
5 kx that might fall outside the scope of your policy.
5 kx @end enumerate
5 kx
5 kx
5 kx @node Security Considerations for find
5 kx @section Security Considerations for @code{find}
5 kx
5 kx
5 kx Some of the actions @code{find} might take have a direct effect;
5 kx these include @code{-exec} and @code{-delete}. However, it is also
5 kx common to use @code{-print} explicitly or implicitly, and so if
5 kx @code{find} produces the wrong list of file names, that can also be a
5 kx security problem; consider the case for example where @code{find} is
5 kx producing a list of files to be deleted.
5 kx
5 kx We normally assume that the @code{find} command line expresses the
5 kx file selection criteria and actions that the user had in mind -- that
5 kx is, the command line is ``trusted'' data.
5 kx
5 kx From a security analysis point of view, the output of @code{find}
5 kx should be correct; that is, the output should contain only the names
5 kx of those files which meet the user's criteria specified on the command
5 kx line. This applies for the @code{-exec} and @code{-delete} actions;
5 kx one can consider these to be part of the output.
5 kx
5 kx On the other hand, the contents of the filesystem can be manipulated
5 kx by other people, and hence we regard this as ``untrusted'' data. This
5 kx implies that the @code{find} command line is a filter which converts
5 kx the untrusted contents of the filesystem into a correct list of output
5 kx files.
5 kx
5 kx The filesystem will in general change while @code{find} is searching
5 kx it; in fact, most of the potential security problems with @code{find}
5 kx relate to this issue in some way.
5 kx
5 kx @dfn{Race conditions} are a general class of security problem where the
5 kx relative ordering of actions taken by @code{find} (for example) and
5 kx something else are critically important in getting the correct and expected result@footnote{This is more or less the
5 kx definition of the term ``race condition''} .
5 kx
5 kx For @code{find}, an attacker might move or rename files or directories in
5 kx the hope that an action might be taken against a file which was not
5 kx normally intended to be affected. Alternatively, this sort of attack
5 kx might be intended to persuade @code{find} to search part of the
5 kx filesystem which would not normally be included in the search
5 kx (defeating the @code{-prune} action for example).
5 kx
5 kx @menu
5 kx * Problems with -exec and filenames::
5 kx * Changing the Current Working Directory::
5 kx * Race Conditions with -exec::
5 kx * Race Conditions with -print and -print0::
5 kx @end menu
5 kx
5 kx @node Problems with -exec and filenames
5 kx @subsection Problems with @code{-exec} and filenames
5 kx
5 kx It is safe in many cases to use the @samp{-execdir} action with any
5 kx file name. Because @samp{-execdir} prefixes the arguments it passes
5 kx to programs with @samp{./}, you will not accidentally pass an argument
5 kx which is interpreted as an option. For example the file @file{-f}
5 kx would be passed to @code{rm} as @file{./-f}, which is harmless.
5 kx
5 kx However, your degree of safety does depend on the nature of the
5 kx program you are running. For example constructs such as these two commands
5 kx
5 kx @example
5 kx # risky
5 kx find -exec sh -c "something @{@}" \;
5 kx find -execdir sh -c "something @{@}" \;
5 kx @end example
5 kx
5 kx are very dangerous. The reason for this is that the @samp{@{@}} is
5 kx expanded to a filename which might contain a semicolon or other
5 kx characters special to the shell. If for example someone creates the
5 kx file @file{/tmp/foo; rm -rf $HOME} then the two commands above could
5 kx delete someone's home directory.
5 kx
5 kx So for this reason do not run any command which will pass untrusted
5 kx data (such as the names of files) to commands which interpret
5 kx arguments as commands to be further interpreted (for example
5 kx @samp{sh}).
5 kx
5 kx In the case of the shell, there is a clever workaround for this
5 kx problem:
5 kx
5 kx @example
5 kx # safer
5 kx find -exec sh -c 'something "$@@"' sh @{@} \;
5 kx find -execdir sh -c 'something "$@@"' sh @{@} \;
5 kx @end example
5 kx
5 kx This approach is not guaranteed to avoid every problem, but it is much
5 kx safer than substituting data of an attacker's choice into the text of
5 kx a shell command.
5 kx
5 kx @node Changing the Current Working Directory
5 kx @subsection Changing the Current Working Directory
5 kx
5 kx As @code{find} searches the filesystem, it finds subdirectories and
5 kx then searches within them by changing its working directory. First,
5 kx @code{find} reaches and recognises a subdirectory. It then decides if that
5 kx subdirectory meets the criteria for being searched; that is, any
5 kx @samp{-xdev} or @samp{-prune} expressions are taken into account. The
5 kx @code{find} program will then change working directory and proceed to
5 kx search the directory.
5 kx
5 kx A race condition attack might take the form that once the checks
5 kx relevant to @samp{-xdev} and @samp{-prune} have been done, an attacker
5 kx might rename the directory that was being considered, and put in its
5 kx place a symbolic link that actually points somewhere else.
5 kx
5 kx The idea behind this attack is to fool @code{find} into going into the
5 kx wrong directory. This would leave @code{find} with a working
5 kx directory chosen by an attacker, bypassing any protection apparently
5 kx provided by @samp{-xdev} and @samp{-prune}, and any protection
5 kx provided by being able to @emph{not} list particular directories on
5 kx the @code{find} command line. This form of attack is particularly
5 kx problematic if the attacker can predict when the @code{find} command
5 kx will be run, as is the case with @code{cron} tasks for example.
5 kx
5 kx GNU @code{find} has specific safeguards to prevent this general class
5 kx of problem. The exact form of these safeguards depends on the
5 kx properties of your system.
5 kx
5 kx @menu
5 kx * O_NOFOLLOW:: Safely changing directory using @code{fchdir}.
5 kx * Systems without O_NOFOLLOW:: Checking for symbolic links after @code{chdir}.
5 kx @end menu
5 kx
5 kx @node O_NOFOLLOW
5 kx @subsubsection @code{O_NOFOLLOW}
5 kx
5 kx If your system supports the @code{O_NOFOLLOW} flag @footnote{GNU/Linux
5 kx (kernel version 2.1.126 and later) and FreeBSD (3.0-CURRENT and later)
5 kx support this} to the @code{open(2)} system call, @code{find} uses it
5 kx to safely change directories. The target directory is first opened
5 kx and then @code{find} changes working directory with the
5 kx @code{fchdir()} system call. This ensures that symbolic links are not
5 kx followed, preventing the sort of race condition attack in which use
5 kx is made of symbolic links.
5 kx
5 kx If for any reason this approach does not work, @code{find} will fall
5 kx back on the method which is normally used if @code{O_NOFOLLOW} is not
5 kx supported.
5 kx
5 kx You can tell if your system supports @code{O_NOFOLLOW} by running
5 kx
5 kx @example
5 kx find --version
5 kx @end example
5 kx
5 kx This will tell you the version number and which features are enabled.
5 kx For example, if I run this on my system now, this gives:
5 kx @example
5 kx find (GNU findutils) 4.8.0
5 kx Copyright (C) 2021 Free Software Foundation, Inc.
5 kx License GPLv3+: GNU GPL version 3 or later \
5 kx <https://gnu.org/licenses/gpl.html>.
5 kx This is free software: you are free to change and redistribute it.
5 kx There is NO WARRANTY, to the extent permitted by law.
5 kx
5 kx Written by Eric B. Decker, James Youngman, and Kevin Dalley.
5 kx Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION \
5 kx FTS(FTS_CWDFD) CBO(level=2)
5 kx @end example
5 kx
5 kx Here, you can see that I am running a version of @code{find} which was
5 kx built from the development (git) code prior to the release of
5 kx findutils-4.5.12, and that several features including @code{O_NOFOLLOW} are
5 kx present. @code{O_NOFOLLOW} is qualified with ``enabled''. This simply means
5 kx that the current system seems to support @code{O_NOFOLLOW}. This check is
5 kx needed because it is possible to build @code{find} on a system that
5 kx defines @code{O_NOFOLLOW} and then run it on a system that ignores the
5 kx @code{O_NOFOLLOW} flag. We try to detect such cases at startup by checking
5 kx the operating system and version number; when this happens you will
5 kx see @samp{O_NOFOLLOW(disabled)} instead.
5 kx
5 kx @node Systems without O_NOFOLLOW
5 kx @subsubsection Systems without @code{O_NOFOLLOW}
5 kx
5 kx The strategy for preventing this type of problem on systems that lack
5 kx support for the @code{O_NOFOLLOW} flag is more complex. Each time
5 kx @code{find} changes directory, it examines the directory it is about
5 kx to move to, issues the @code{chdir()} system call, and then checks
5 kx that it has ended up in the subdirectory it expected. If all is as
5 kx expected, processing continues as normal. However, there are two main
5 kx reasons why the directory might change: the use of an automounter and
5 kx someone removing the old directory and replacing it with something
5 kx else while @code{find} is trying to descend into it.
5 kx
5 kx Where a filesystem ``automounter'' is in use it can be the case that
5 kx the use of the @code{chdir()} system call can itself cause a new
5 kx filesystem to be mounted at that point. On systems that do not
5 kx support @code{O_NOFOLLOW}, this will cause @code{find}'s security check to
5 kx fail.
5 kx
5 kx However, this does not normally represent a security problem, since
5 kx the automounter configuration is normally set up by the system
5 kx administrator. Therefore, if the @code{chdir()} sanity check fails,
5 kx @code{find} will make one more attempt@footnote{This may not be the
5 kx case for the fts-based executable}. If that succeeds, execution
5 kx carries on as normal. This is the usual case for automounters.
5 kx
5 kx Where an attacker is trying to exploit a race condition, the problem
5 kx may not have gone away on the second attempt. If this is the case,
5 kx @code{find} will issue a warning message and then ignore that
5 kx subdirectory. When this happens, actions such as @samp{-exec} or
5 kx @samp{-print} may already have taken place for the problematic
5 kx subdirectory. This is because @code{find} applies tests and actions
5 kx to directories before searching within them (unless @samp{-depth} was
5 kx specified).
5 kx
5 kx Because of the nature of the directory-change operation and security
5 kx check, in the worst case the only things that @code{find} would have
5 kx done with the directory are to move into it and back out to the
5 kx original parent. No operations would have been performed within that
5 kx directory.
5 kx
5 kx @node Race Conditions with -exec
5 kx @subsection Race Conditions with @code{-exec}
5 kx
5 kx The @samp{-exec} action causes another program to be run. It passes
5 kx to the program the name of the file which is being considered at the
5 kx time. The invoked program will typically then perform some action
5 kx on that file. Once again, there is a race condition which can be
5 kx exploited here. We shall take as a specific example the command
5 kx
5 kx @example
5 kx find /tmp -path /tmp/umsp/passwd -exec /bin/rm
5 kx @end example
5 kx
5 kx In this simple example, we are identifying just one file to be deleted
5 kx and invoking @code{/bin/rm} to delete it. A problem exists because
5 kx there is a time gap between the point where @code{find} decides that
5 kx it needs to process the @samp{-exec} action and the point where the
5 kx @code{/bin/rm} command actually issues the @code{unlink()} system
5 kx call to delete the file from the filesystem. Within this time period, an attacker can rename the
5 kx @file{/tmp/umsp} directory, replacing it with a symbolic link to
5 kx @file{/etc}. There is no way for @code{/bin/rm} to determine that it
5 kx is working on the same file that @code{find} had in mind. Once the
5 kx symbolic link is in place, the attacker has persuaded @code{find} to
5 kx cause the deletion of the @file{/etc/passwd} file, which is not the
5 kx effect intended by the command which was actually invoked.
5 kx
5 kx One possible defence against this type of attack is to modify the
5 kx behaviour of @samp{-exec} so that the @code{/bin/rm} command is run
5 kx with the argument @file{./passwd} and a suitable choice of working
5 kx directory. This would allow the normal sanity check that @code{find}
5 kx performs to protect against this form of attack too. Unfortunately,
5 kx this strategy cannot be used as the POSIX standard specifies that the
5 kx current working directory for commands invoked with @samp{-exec} must
5 kx be the same as the current working directory from which @code{find}
5 kx was invoked. This means that the @samp{-exec} action is inherently
5 kx insecure and can't be fixed.
5 kx
5 kx GNU @code{find} implements a more secure variant of the @samp{-exec}
5 kx action, @samp{-execdir}. The @samp{-execdir} action
5 kx ensures that it is not necessary to dereference subdirectories to
5 kx process target files. The current directory used to invoke programs
5 kx is the same as the directory in which the file to be processed exists
5 kx (@file{/tmp/umsp} in our example, and only the basename of the file to
5 kx be processed is passed to the invoked command, with a @samp{./}
5 kx prepended (giving @file{./passwd} in our example).
5 kx
5 kx The @samp{-execdir} action refuses to do anything if the current
5 kx directory is included in the @var{$PATH} environment variable. This
5 kx is necessary because @samp{-execdir} runs programs in the same
5 kx directory in which it finds files -- in general, such a directory
5 kx might be writable by untrusted users. For similar reasons,
5 kx @samp{-execdir} does not allow @samp{@{@}} to appear in the name of
5 kx the command to be run.
5 kx
5 kx @node Race Conditions with -print and -print0
5 kx @subsection Race Conditions with @code{-print} and @code{-print0}
5 kx
5 kx The @samp{-print} and @samp{-print0} actions can be used to produce a
5 kx list of files matching some criteria, which can then be used with some
5 kx other command, perhaps with @code{xargs}. Unfortunately, this means
5 kx that there is an unavoidable time gap between @code{find} deciding
5 kx that one or more files meet its criteria and the relevant command
5 kx being executed. For this reason, the @samp{-print} and @samp{-print0}
5 kx actions are just as insecure as @samp{-exec}.
5 kx
5 kx In fact, since the construction
5 kx
5 kx @example
5 kx find @dots{} -print | xargs @enddots{}
5 kx @end example
5 kx
5 kx does not cope correctly with newlines or other ``white space'' in
5 kx file names, and copes poorly with file names containing quotes, the
5 kx @samp{-print} action is less secure even than @samp{-print0}.
5 kx
5 kx
5 kx @comment node-name, next, previous, up
5 kx @comment @node Security Considerations for xargs
5 kx @node Security Considerations for xargs
5 kx @section Security Considerations for @code{xargs}
5 kx
5 kx The description of the race conditions affecting the @samp{-print}
5 kx action of @code{find} shows that @code{xargs} cannot be secure if it
5 kx is possible for an attacker to modify a filesystem after @code{find}
5 kx has started but before @code{xargs} has completed all its actions.
5 kx
5 kx However, there are other security issues that exist even if it is not
5 kx possible for an attacker to have access to the filesystem in real
5 kx time. Firstly, if it is possible for an attacker to create files with
5 kx names of their choice on the filesystem, then @code{xargs} is
5 kx insecure unless the @samp{-0} option is used. If a file with the name
5 kx @file{/home/someuser/foo/bar\n/etc/passwd} exists (assume that
5 kx @samp{\n} stands for a newline character), then @code{find @dots{} -print}
5 kx can be persuaded to print three separate lines:
5 kx
5 kx @example
5 kx /home/someuser/foo/bar
5 kx
5 kx /etc/passwd
5 kx @end example
5 kx
5 kx If it finds a blank line in the input, @code{xargs} will ignore it.
5 kx Therefore, if some action is to be taken on the basis of this list of
5 kx files, the @file{/etc/passwd} file would be included even if this was
5 kx not the intent of the person running find. There are circumstances in
5 kx which an attacker can use this to their advantage. The same
5 kx consideration applies to file names containing ordinary spaces rather
5 kx than newlines, except that of course the list of file names will no
5 kx longer contain an ``extra'' newline.
5 kx
5 kx This problem is an unavoidable consequence of the default behaviour of
5 kx the @code{xargs} command, which is specified by the POSIX standard.
5 kx The only ways to avoid this problem are either to avoid all use of
5 kx @code{xargs} in favour for example of @samp{find -exec} or (where
5 kx available) @samp{find -execdir}, or to use the @samp{-0} option, which
5 kx ensures that @code{xargs} considers file names to be separated by
5 kx ASCII NUL characters rather than whitespace. However, useful as this
5 kx option is, the POSIX standard does not make it mandatory.
5 kx
5 kx POSIX also specifies that @code{xargs} interprets quoting and trailing
5 kx whitespace specially in filenames, too. This means that using
5 kx @code{find ... -print | xargs ...} can cause the commands run by
5 kx @code{xargs} to receive a list of file names which is not the same as
5 kx the list printed by @code{find}. The interpretation of quotes and
5 kx trailing whitespace is turned off by the @samp{-0} argument to
5 kx @code{xargs}, which is another reason to use that option.
5 kx
5 kx @comment node-name, next, previous, up
5 kx @node Security Considerations for locate
5 kx @section Security Considerations for @code{locate}
5 kx
5 kx @subsection Race Conditions
5 kx It is fairly unusual for the output of @code{locate} to be fed into
5 kx another command. However, if this were to be done, this would raise
5 kx the same set of security issues as the use of @samp{find @dots{} -print}.
5 kx Although the problems relating to whitespace in file names can be
5 kx resolved by using @code{locate}'s @samp{-0} option, this still leaves
5 kx the race condition problems associated with @samp{find @dots{} -print0}.
5 kx There is no way to avoid these problems in the case of @code{locate}.
5 kx
5 kx @node Security Summary
5 kx @section Summary
5 kx
5 kx Where untrusted parties can create files on the system, or affect the
5 kx names of files that are created, all uses for @code{find},
5 kx @code{locate} and @code{xargs} have known security problems except the
5 kx following:
5 kx
5 kx @table @asis
5 kx @item Informational use only
5 kx Uses where the programs are used to prepare lists of file names upon
5 kx which no further action will ever be taken.
5 kx
5 kx @item @samp{-delete}
5 kx Use of the @samp{-delete} action with @code{find} to delete files
5 kx which meet specified criteria
5 kx
5 kx @item @samp{-execdir}
5 kx Use of the @samp{-execdir} action with @code{find} where the
5 kx @env{PATH} environment variable contains directories which contain
5 kx only trusted programs.
5 kx @end table
5 kx
5 kx
5 kx @node Further Reading on Security
5 kx @section Further Reading on Security
5 kx
5 kx While there are a number of books on computer security, there are also
5 kx useful articles on the web that touch on the issues described above:
5 kx
5 kx @table @url
5 kx @item https://goo.gl/DAvh
5 kx @c https://www.securecoding.cert.org/confluence/display/seccode/MSC09-C.+Character+Encoding+-+Use+Subset+of+ASCII+for+Safety
5 kx This article describes some of the unfortunate effects of allowing
5 kx free choice of file names.
5 kx @item https://cwe.mitre.org/data/definitions/78.html
5 kx Describes OS Command Injection
5 kx @item https://cwe.mitre.org/data/definitions/73.html
5 kx Describes problems arising from allowing remote computers to send
5 kx requests which specify file names of their choice
5 kx @item https://cwe.mitre.org/data/definitions/116.html
5 kx Describes problems relating to encoding file names and escaping
5 kx characters. This article is relevant to findutils because for command
5 kx lines processed via the shell, the encoding and escaping rules are
5 kx already set by the shell. For example command lines like @code{find
5 kx ... -print | some-shell-script} require specific care.
5 kx @item https://xkcd.com/327/
5 kx A humorous and pithy summary of the broader problem.
5 kx @end table
5 kx
5 kx @comment node-name, next, previous, up
5 kx @node Error Messages
5 kx @chapter Error Messages
5 kx
5 kx This section describes some of the error messages sometimes made by
5 kx @code{find}, @code{xargs}, or @code{locate}, explains them and in some
5 kx cases provides advice as to what you should do about this.
5 kx
5 kx This manual is written in English. The GNU findutils software
5 kx features translations of error messages for many languages. For this
5 kx reason the error messages produced by the programs are made to be as
5 kx self-explanatory as possible. This approach avoids leaving people to
5 kx figure out which test an English-language error message corresponds
5 kx to. Error messages which are self-explanatory will not normally be
5 kx mentioned in this document. For those messages mentioned in this
5 kx document, only the English-language version of the message will be
5 kx listed.
5 kx
5 kx @menu
5 kx * Error Messages From find::
5 kx * Error Messages From xargs::
5 kx * Error Messages From locate::
5 kx * Error Messages From updatedb::
5 kx @end menu
5 kx
5 kx @node Error Messages From find
5 kx @section Error Messages From @code{find}
5 kx
5 kx Most error messages produced by find are self-explanatory. Error
5 kx messages sometimes include a filename. When this happens, the
5 kx filename is quoted in order to prevent any unusual characters in the
5 kx filename making unwanted changes in the state of the terminal.
5 kx
5 kx @table @samp
5 kx @item invalid predicate `-foo'
5 kx This means that the @code{find} command line included something that
5 kx started with a dash or other special character. The @code{find}
5 kx program tried to interpret this as a test, action or option, but
5 kx didn't recognise it. If it was intended to be a test, check what was
5 kx specified against the documentation. If, on the other hand, the
5 kx string is the name of a file which has been expanded from a wildcard
5 kx (for example because you have a @samp{*} on the command line),
5 kx consider using @samp{./*} or just @samp{.} instead.
5 kx
5 kx @item unexpected extra predicate
5 kx This usually happens if you have an extra bracket on the command line
5 kx (for example @samp{find . -print \)}).
5 kx
5 kx @item Warning: filesystem /path/foo has recently been mounted
5 kx @itemx Warning: filesystem /path/foo has recently been unmounted
5 kx These messages might appear when @code{find} moves into a directory
5 kx and finds that the device number and inode are different from what it
5 kx expected them to be. If the directory @code{find} has moved into is
5 kx on a network filesystem (NFS), it will not issue this message, because
5 kx @code{automount} frequently mounts new filesystems on directories as
5 kx you move into them (that is how it knows you want to use the
5 kx filesystem). So, if you do see this message, be wary --
5 kx @code{automount} may not have been responsible. Consider the
5 kx possibility that someone else is manipulating the filesystem while
5 kx @code{find} is running. Some people might do this in order to mislead
5 kx @code{find} or persuade it to look at one set of files when it thought
5 kx it was looking at another set.
5 kx
5 kx @item /path/foo changed during execution of find (old device number 12345, new device number 6789, filesystem type is <whatever>) [ref XXX]
5 kx This message is issued when @code{find} moves into a directory and ends up
5 kx somewhere it didn't expect to be. This happens in one of two
5 kx circumstances. Firstly, this happens when @code{automount} intervenes
5 kx on a system where @code{find} doesn't know how to determine what
5 kx the current set of mounted filesystems is.
5 kx
5 kx Secondly, this can happen when the device number of a directory
5 kx appears to change during a change of current directory, but
5 kx @code{find} is moving up the filesystem hierarchy rather than down into it.
5 kx In order to prevent @code{find} wandering off into some unexpected
5 kx part of the filesystem, we stop it at this point.
5 kx
5 kx @item Don't know how to use getmntent() to read `/etc/mtab'. This is a bug.
5 kx This message is issued when a problem similar to the above occurs on a
5 kx system where @code{find} doesn't know how to figure out the current
5 kx list of mount points. Ask for help on @email{bug-findutils@@gnu.org}.
5 kx
5 kx @item /path/foo/bar changed during execution of find (old inode number 12345, new inode number 67893, filesystem type is <whatever>) [ref XXX]"),
5 kx This message is issued when @code{find} moves into a directory and
5 kx discovers that the inode number of that directory
5 kx is different from the inode number that it obtained when it examined the
5 kx directory previously. This usually means that while
5 kx @code{find} was deep in a directory hierarchy doing a
5 kx time consuming operation, somebody has moved one of the parent directories to
5 kx another location in the same filesystem. This may or may not have been done
5 kx maliciously. In any case, @code{find} stops at this point
5 kx to avoid traversing parts of the filesystem that it wasn't
5 kx intended to. You can use @code{ls -li} or @code{find /path -inum
5 kx 12345 -o -inum 67893} to find out more about what has happened.
5 kx
5 kx @item sanity check of the fnmatch() library function failed.
5 kx Please submit a bug report. You may well be asked questions about
5 kx your system, and if you compiled the @code{findutils} code yourself,
5 kx you should keep your copy of the build tree around. The likely
5 kx explanation is that your system has a buggy implementation of
5 kx @code{fnmatch} that looks enough like the GNU version to fool
5 kx @code{configure}, but which doesn't work properly.
5 kx
5 kx @item cannot fork
5 kx This normally happens if you use the @code{-exec} action or
5 kx something similar (@code{-ok} and so forth) but the system has run out
5 kx of free process slots. This is either because the system is very busy
5 kx and the system has reached its maximum process limit, or because you
5 kx have a resource limit in place and you've reached it. Check the
5 kx system for runaway processes (with @code{ps}, if possible). Some process
5 kx slots are normally reserved for use by @samp{root}.
5 kx
5 kx @item some-program terminated by signal 99
5 kx Some program which was launched with @code{-exec} or similar was killed
5 kx with a fatal signal. This is just an advisory message.
5 kx @end table
5 kx
5 kx
5 kx @node Error Messages From xargs
5 kx @section Error Messages From @code{xargs}
5 kx
5 kx @table @samp
5 kx @item environment is too large for exec
5 kx This message means that you have so many environment variables set (or
5 kx such large values for them) that there is no room within the
5 kx system-imposed limits on program command line argument length to
5 kx invoke any program. This is an unlikely situation and is more likely
5 kx result of an attempt to test the limits of @code{xargs}, or break it.
5 kx Please try unsetting some environment variables, or exiting the
5 kx current shell. You can also use @samp{xargs --show-limits} to
5 kx understand the relevant sizes.
5 kx
5 kx @item argument list too long
5 kx You are using the @samp{-I} option and @code{xargs} doesn't have
5 kx enough space to build a command line because it has read a really
5 kx large item and it doesn't fit. You may be able to work around this
5 kx problem with the @samp{-s} option, but the default size is pretty
5 kx large. This is a rare situation and is more likely an attempt to test
5 kx the limits of @code{xargs}, or break it. Otherwise, you will need to
5 kx try to shorten the problematic argument or not use @code{xargs}.
5 kx
5 kx @item argument line too long
5 kx You are using the @samp{-L} or @samp{-l} option and one of the input
5 kx lines is too long. You may be able to work around this problem with
5 kx the @samp{-s} option, but the default size is pretty large. If you
5 kx can modify the your @code{xargs} command not to use @samp{-L} or
5 kx @samp{-l}, that will be more likely to result in success.
5 kx
5 kx @item cannot fork
5 kx See the description of the similar message for @code{find}.
5 kx
5 kx @item <program>: exited with status 255; aborting
5 kx When a command run by @code{xargs} exits with status 255, @code{xargs}
5 kx is supposed to stop. If this is not what you intended, wrap the
5 kx program you are trying to invoke in a shell script which doesn't
5 kx return status 255.
5 kx
5 kx @item <program>: terminated by signal 99
5 kx See the description of the similar message for @code{find}.
5 kx
5 kx @item cannot set SIGUSR1 signal handler
5 kx @code{xargs} is having trouble preparing for you to be able to send it
5 kx signals to increase or decrease the parallelism of its processing.
5 kx If you don't plan to send it those signals, this warning can be ignored
5 kx (though if you're a programmer, you may want to help us figure out
5 kx why @code{xargs} is confused by your operating system).
5 kx
5 kx @item failed to redirect standard input of the child process
5 kx @code{xargs} redirects the stdin stream of the command to be run to either
5 kx @file{/dev/null} or to @file{/dev/tty} for the @samp{-o} option.
5 kx See the manual of the system call @code{dup2(2)}.
5 kx @end table
5 kx
5 kx @node Error Messages From locate
5 kx @section Error Messages From @code{locate}
5 kx
5 kx @table @samp
5 kx @item warning: database @file{@value{LOCATE_DB}} is more than 8 days old
5 kx The @code{locate} program relies on a database which is periodically
5 kx built by the @code{updatedb} program. That hasn't happened in a long
5 kx time. To fix this problem, run @code{updatedb} manually. This can
5 kx often happen on systems that are generally not left on, so the
5 kx periodic ``cron'' task which normally does this doesn't get a chance
5 kx to run.
5 kx
5 kx @item locate database @file{@value{LOCATE_DB}} is corrupt or invalid
5 kx This should not happen. Re-run @code{updatedb}. If that works, but
5 kx @code{locate} still produces this error, run @code{locate --version}
5 kx and @code{updatedb --version}. These should produce the same output.
5 kx If not, you are using a mixed toolset; check your @samp{$PATH}
5 kx environment variable and your shell aliases (if you have any). If
5 kx both programs claim to be GNU versions, this is a bug; all versions of
5 kx these programs should interoperate without problem. Ask for help on
5 kx @email{bug-findutils@@gnu.org}.
5 kx @end table
5 kx
5 kx
5 kx @node Error Messages From updatedb
5 kx @section Error Messages From @code{updatedb}
5 kx
5 kx The @code{updatedb} program (and the programs it invokes) do issue
5 kx error messages, but none seem to be candidates for guidance. If
5 kx you are having a problem understanding one of these, ask for help on
5 kx @email{bug-findutils@@gnu.org}.
5 kx
5 kx @node GNU Free Documentation License
5 kx @appendix GNU Free Documentation License
5 kx @include fdl.texi
5 kx
5 kx @node Primary Index
5 kx @unnumbered @code{find} Primary Index
5 kx
5 kx This is a list of all of the primaries (tests, actions, and options)
5 kx that make up @code{find} expressions for selecting files. @xref{find
5 kx Expressions}, for more information on expressions.
5 kx
5 kx @printindex fn
5 kx
5 kx @bye
5 kx
5 kx @comment texi related words used by Emacs' spell checker ispell.el
5 kx
5 kx @comment LocalWords: texinfo setfilename settitle setchapternewpage
5 kx @comment LocalWords: iftex finalout ifinfo DIR titlepage vskip pt
5 kx @comment LocalWords: filll dir samp dfn noindent xref pxref
5 kx @comment LocalWords: var deffn texi deffnx itemx emph asis
5 kx @comment LocalWords: findex smallexample subsubsection cindex
5 kx @comment LocalWords: dircategory direntry itemize
5 kx
5 kx @comment other words used by Emacs' spell checker ispell.el
5 kx @comment LocalWords: README fred updatedb xargs Plett Rendell akefile
5 kx @comment LocalWords: args grep Filesystems fo foo fOo wildcards iname
5 kx @comment LocalWords: ipath regex iregex expr fubar regexps
5 kx @comment LocalWords: metacharacters macs sr sc inode lname ilname
5 kx @comment LocalWords: sysdep noleaf ls inum xdev filesystems usr atime
5 kx @comment LocalWords: ctime mtime amin cmin mmin al daystart Sladkey rm
5 kx @comment LocalWords: anewer cnewer bckw rf xtype uname gname uid gid
5 kx @comment LocalWords: nouser nogroup chown chgrp perm ch maxdepth
5 kx @comment LocalWords: mindepth cpio src CD AFS statted stat fstype ufs
5 kx @comment LocalWords: nfs tmp mfs printf fprint dils rw djm Nov lwall
5 kx @comment LocalWords: POSIXLY fls fprintf strftime locale's EDT GMT AP
5 kx @comment LocalWords: EST diff perl backquotes sprintf Falstad Oct cron
5 kx @comment LocalWords: eg vmunix mkdir afs allexec allwrite ARG bigram
5 kx @comment LocalWords: bigrams cd chmod comp crc CVS dbfile eof
5 kx @comment LocalWords: fileserver filesystem fn frcode Ghazi Hnewc iXX
5 kx @comment LocalWords: joeuser Kaveh localpaths localuser LOGNAME
5 kx @comment LocalWords: Meyering mv netpaths netuser nonblank nonblanks
5 kx @comment LocalWords: ois ok Pinard printindex proc procs prunefs
5 kx @comment LocalWords: prunepaths pwd RFS rmadillo rmdir rsh sbins str
5 kx @comment LocalWords: su Timar ubins ug unstripped vf VM Weitzel
5 kx @comment LocalWords: wildcard zlogout basename execdir wholename iwholename
5 kx @comment LocalWords: timestamp timestamps Solaris FreeBSD OpenBSD POSIX