Why backslash before asterisk in `find`?

9

5

In this command:

find . -name \*.pyc -delete

Why is a backslash needed before *.pyc ?

Ram Rachum

Posted 2014-05-04T13:31:49.580

Reputation: 4 261

The man page for find should have a section called NON-BUGS with something similar as an example and an explanation of why it is needed. – Brian – 2014-05-04T13:37:42.110

Answers

19

An unquoted glob would be expanded by the shell before find is executed. (Refer to Filename Expansion in the manual.)

So saying:

find . -name *.pyc -delete

would actually execute:

find . -name file1.pyc file2.pyc file3.pyc -delete

assuming there were 3 .pyc files in the current directory and result in an error instead.

A backslash makes the shell pass the glob to find, i.e. it acts as if *.pyc were quoted.

Ideally, you should be quoting a glob:

find . -name '*.pyc' -delete

devnull

Posted 2014-05-04T13:31:49.580

Reputation: 2 987

@RamRachum, but more character when typing. – Paul Draper – 2014-05-05T00:39:31.827

1@PaulDraper Readable and less prone to mistakes > Shorter by one keystroke – Doorknob – 2014-05-05T01:17:27.647

Single quotes are the way to go. I never even thought you could use the backslash in this way... – Floris – 2014-05-05T04:45:20.733

4

Before your shell issues the find command, it will do various expansions. Doing so, it also processes special characters (or, characters with special meaning), where * is a wildcard – a globbing character. This is the so-called filename expansion.

Say you have two files in your directory:

  • foo.pyc
  • bar.pyc

Then *.pyc would expand to both names. So if you write:

find . -name *.pyc -delete

then the shell will actually call:

find . -name foo.pyc bar.pyc -delete

which does not make a lot of sense, because you can only have one argument for -name. That's why you need to escape the special character to prevent it from being interpreted by the shell. You do that by backslash-escaping, or alternatively, quoting it.

slhck

Posted 2014-05-04T13:31:49.580

Reputation: 182 472