What is the difference between the two below:
find . -type f -name \*.bmp
find . -type f -name *.bmp
I have tested,they both return the same result,so is there anything different _deep inside_
?
Added from the removed answer:
So it is to avoid the shell expansion for the special ***** character,solely pass * as a argument to the find command and let it process it.
But on my machine,they are all good, both return the bmp files in and below the current directory,to name a few,the result is like below,some are omitted for brevity
./images/building_color.bmp
./images/building_gray.bmp
./images/car_gray.bmp
./images/temple_color.bmp
./images/boat_gray.bmp
./images/tools_gray.bmp
./images/temple_gray.bmp
./images/tools_color.bmp
./images/car_color.bmp
./images/boat_color.bmp
system info:
GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
Linux sysabod-laptop 2.6.32-30-generic #59-Ubuntu SMP Tue Mar 1 21:30:21 UTC 2011 i686 GNU/Linux
Here's how they're different: the first one always works, and the second one doesn't.
As for why: in bash, shell globs (wildcard patterns including * or ?) are expanded by the shell into all files matching the glob. However, if no such files exist, the pattern is left alone.
So, if you're in a directory with no bmp
files, the commands work the same way, because the first is escaped and bash fails to find any files matching in the second case.
If you ran it from a directory containing only one such file, say foo.bmp
, the first would find all bmp
files in the subtree, while the second would find all files named foo.bmp
only. If run in a directory with multiple bmp
files, I believe you'll get an error because find
doesn't know what to do with all the filenames.
When you escape the asterisk (\*
) the asterisk itself is passed as argument to the find
command and will be evaluated by find
. If you don't escape the asterisk (*
) already the shell evaluates it and expands it to the file names matching the pattern.
Fore example consider following directory structure:
./a.txt
./b.bmp
./c.bmp
./dir/d.doc
./dir/e.bmp
When you execute
find . -type f -name *.bmp
the shell expands *.bmp
to b.bmp c.bmp
. I.e. the command that is actually executed will be:
find . -type f -name b.bmp c.bmp
which will find b.bmp
and c.bmp
but not dir/e.bmp
.
When you execute
find . -type f -name \*.bmp
*.bmp
is passed directly as it is to find
. find
will recurse through the current directory (.
) and all its subdirectories (in the example only dir
) and will find all files in those directories matching the pattern. The result will be: b.bmp
, c.bmp
and also dir/e.bmp
.
The first command:
find . -type f -name \*.bmp
passes an asterisk to the find
command, and that tells it to find all the files in and below the current directory ending with .bmp.
The second command:
find . -type f -name *.bmp
may be resolved by the shell to, for example:
find . -type f -name image1.bmp image2.bmp image3.bmp
(that would be the bmp files in the current directory only)
and find
would only list them, not the bmp files in other directories below the current one.