For reproducing the problem I created all the files as shown in the longer Result in the question.
When I define the function(*) as
function find
{
command find $@ -exec ls --color=auto -d {} \;
}
and execute
find ./ -name '*.pl' -or -name '*.pm'
I get an error message
find: paths must precede expression: fs2db.pl
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
because *.pl
gets expanded to auth.pl fs2db.pl index.pl title.pl
by the shell.
I had to change the function to
function find
{
command find "$@" -exec ls --color=auto -d {} \;
}
to reproduce your problem. (Maybe this depends on the shell. I tested with bash 4.4.19(3)-release)
After set -x
you can see what the shell does when executing your function:
$ find ./ -name '*.pl' -or -name '*.pm'
+ find ./ -name '*.pl' -or -name '*.pm'
+ command find ./ -name '*.pl' -or -name '*.pm' -exec ls --color=auto -d '{}' ';'
+ find ./ -name '*.pl' -or -name '*.pm' -exec ls --color=auto -d '{}' ';'
./lib/cover.pm
./lib/db.pm
The difference between executing your function and executing the find
command directly is that your function appends an -exec
action with the implicit -a
(AND) operator. Without an explicit action, find
prints all matching results.
You see a result of the operator precedence -a
(AND) higher than -o
(=-or
, OR)
You can compare the output of these 3 commands
command find ./ -name '*.pl' -or -name '*.pm'
command find ./ -name '*.pl' -or -name '*.pm' -print
command find ./ \( -name '*.pl' -or -name '*.pm' \) -print
see http://man7.org/linux/man-pages/man1/find.1.html#NON-BUGS
You can call your function as
find ./ \( -name '*.pl' -or -name '*.pm' \)
to avoid the problem.
(*) This function definition is copied from the question.
You should use the portable POSIX style find() { ... }
instead, unless there is a specific requirement for the Korn shell style function find { ... }
.