Why I can find *main.o but cannot *.o?

This one is correct:

$ find . -name *main.o
./main.o

So, why I can't find *.o?

$ find . -name *.o
find: paths must precede expression: main.o
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

Solution 1:

Probably there are more than one file that match *.o, while only one file match *main.o, so, in the first case, shell expansion runs:

$ find . -name main.o

and this works. In the second case:

$ find . -name file1.o main.o

And this is why you got error.

In order to prevent this, you should quote expression in both command:

$ find . -name '*.o'
$ find . -name '*main.o'

Solution 2:

Put the file pattern in quotes. Otherwise, * is expanded by the shell (resolved to a list of files before find sees it), confusing find.

find . -name "*.o"