Question: I'm trying to colourize my find command so I've added this alias function to my .bashrc.

```
# liberate your find
function find
{
    command find $@ -exec ls --color=auto -d {} \;
}

```

But there is unexpected behavior using this code. It drops my quotes.

GNU bash, version 4.4.23(1)-release (x86\_64-pc-linux-gnu)

Use my function:

```
find ./ -name '*.pl' -or -name '*.pm'

```

Result:

```
./lib/cover.pm
./lib/db.pm

```

Using the same find function but built-in:

```
command find ./ -name '*.pl' -or -name '*.pm'

```

Result:

```
./auth.pl
./index.pl
./title.pl
./lib/cover.pm
./lib/db.pm
./fs2db.pl

```

So the second variant didn't eat my quotes and works as it should.

Answer: 
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

```none
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 { ... }`.
As written, the `-exec` primary only applies to the code on the right of the `-or` operator. You need to parenthesize your arguments so that `-exec` applies to *everything* that matches. You also need to extract the path from the other arguments (which gets messy if you want to specify multiple paths, as your function would have to decide where to put the parentheses; distinguishing between paths and other expressions would amount to reimplementing a good chunk of `find`'s parsing. I'll assume you are only passing a single path here).

```
find ()
{
    path=$1
    shift
    command find "$path" \( "$@" \) -exec ls --color=auto -d {} \;
}

```

Alternatively, you can put the parentheses in the command line, with no change to your current definition.

```
find ./ \( -name '*.pl' -or -name '*.pm' \)

```

---

Your original function runs

```
find ./ -name '*.pl' -or -name '*.pm' -exec ls --color=auto -d {} \;

```

which is equivalent to 

```
find ./ -name '*.pl' -or \( -name '*.pm' -exec ls --color=auto -d {} \; \)

```

with no implicit `-print`.