2

If I'm in a folder and I want to find the jpg files, I can run

find -type f -name "*jpg"

but I don't understand why I have to use doble quotes. I know without them, pathname expansion will mess up the find command (if there is more than one jpg file in the folder), but do not know exactly why. I don't get too why here the quotes do not avoid expansion by the shell.

10

Both double and single quotes prevent filename expansion in the shell.

Find is somewhat special because it recurses through all the levels of directory.

If you do not quote the -name option in a find command, the shell expands the name expression immediately, in the directory where you run find. That may match the files zero times, one time, or many times.

For no shell matches, the *jpg just gets put back into the command line and passed to find as an option.

For one match, the actual name (e.g. K3256.jpg) is passed to find, which will therefore only look for files in lower directories with that exact name.

For multiple matches, several names will be put into the find command line, and find will refuse to run because the syntax of the arguments will be wrong.

Find itself takes on the responsibility of expanding the wildcard within each directory it descends into. It does not want any misplaced help from the shell.

Shell removes the quotes before invoking the find as a new process. This avoids all programs having to deal with quotes, which are strictly part of shell syntax. When the child process sees the args, they have been converted to an array of null-terminated strings, and do not need further adornment.

The find command understands and actions filename expansion in exactly the same way that shell does. The difference is that find descends through all the levels of directory, and in each directory it reads the list of names in there, and matches every name at that level against the -name pattern.

Note also that the -type f option also does its work within each sub-directory: the directory entries contain that information too, so find has to deal with both the file type and the name match all over again at every branch of the directory tree.

Also see this answer

| improve this answer | |
  • Thanks for the response. But how can the find command work with the quotes if there is no expansion? – fich Jul 3 at 22:46
  • 2
    @fich The find command does pattern matching, which is sort of like expansion. But it can only do that if the shell doesn't expand it first. Quotes prevent the shell from expanding it, but they're removed (by the shell) before find sees the pattern, so they don't prevent find from "expanding" (actually matching) it. – Gordon Davisson Jul 4 at 0:34
  • 1
    Not exactly the same; find ... -name leading ? or * matches dotfiles aka hidden files, which glob in most shells doesn't at least by default. Otherwise thorough and clear :) – dave_thompson_085 Jul 4 at 13:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.