Inconsistency in find ... -name ...

Eric Blake ericblake@comcast.net
Mon May 15 22:06:00 GMT 2006


> Using find, I didn't protect spec in -name (-name 'spec') in a couple of 
> instances but they still worked, viz-a-viz:
>      $ find /home/lowella -type f -name *.h
>      /home/lowella/CVSROOT/src/newlib/doc/ansidecl.h
>      ...
> whereas a couple of others didn't work, viz-a-viz:
>      $ find /home/lowella -type f -name *.txt
>      find: paths must precede expression
>      Usage: find [-H] [-L] [-P] [path...] [expression]

echo is your friend.  Try:

$ echo /home/lowella -type f -name *.h

And notice that since there are no .h files in the current
directory, the shell passes the glob through unchanged
to find.  You can also do 'shopt -s nullglob' to change that.

Then try:
$ echo find /home/lowella -type f -name *.txt

And notice that since there were more than one .txt
files in the current directory, the shell expanded
the glob, and passes each and every file name to
find, rather than "*.txt"; and this is a syntax error
to find.  And had there been only one .txt file in the
current directory, the glob would have expanded,
but then you would only be finding files that match
that exact name, instead of all .txt files.

> Based on my reading of find and bash documentation, perhaps I missed the 
> explanation.

Yes - reread the bash man page, under quoting rules.  Then
realize that find is one of the few programs that does globbing
by itself, but that for find to see the glob, it must be quoted
from the shell.

> 
> Also, I rhetorically ask, why does
>      $ find /home/lowella -type f -name '*.txt'
> work but
>      ls '*.txt'
> doesn't?

Because find must expand globs, but ls does not.  So
ls '*.txt' will fail unless you happen to have a file literally
named *.txt (which is impossible on normal Windows
directories).

By the way, none of this is cygwin specific, nor are
you the first person to ask this question on this
list.  Google is your friend.

Also, I have seen people do (something like) the
following to make it so that shell globbing is
disabled when passing arguments to find (take
this with a grain of salt; I am typing this from memory
without a live test):

$ alias find='_find() { find "$@"; set +f ; }; set -f; _find'


-- 
Eric Blake
volunteer cygwin findutils/bash maintainer

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list