17

In the documentation, I see usage both ways:

find . -type f -exec file '{}' \;

find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \
  • 4
    Sure seems like it has nothing to do with the find, command, and instead has to do with proper quoting for the command being called. – Zoredache Nov 3 '15 at 20:05
  • 1
    Try it with fish, rather than bash. – Charles Duffy Nov 4 '15 at 18:39
24

For the bash shell, '{}' and {} are interchangeable. This is not be the case with all shells (such as fish).

Putting the argument in single quotes explicitly indicates that the curly braces should be sent to find. Depending on the usage, the bash shell sometimes substitutes the contents of curly brackets.

As seen below, bash does not substitute empty brackets, and they get passed to the command. For the find command, it doesn't matter.

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

$ echo '{1,3}'
{1,3}
  • 4
    Doesn't matter with bash. Does matter with fish. – Charles Duffy Nov 4 '15 at 18:40
  • 1
    I'd replace " are interchangeable" with " are interchangeable in some shells, not in all of them. ALWAYS use the single quotes to make sure they get passed as-is to the find command" (good habits starts by making sure you use the correct way even if you happen to (always?) be on a system that allows the ambiguous one) – Olivier Dulac Nov 5 '15 at 13:55
9

With almost all shell interpreters available, there is absolutely no difference between '{}' and {}.

The single quotes are normally used to protect the embedded string from being substituted by something else, for example:

  • 'a b' is a single three characters parameter, without the quotes that would be two single character parameters
  • '$b' is a literally the dollar sign followed by the letter b, without the quote that would be whatever the b variable contains and possibly nothing if unset
  • '!!' are litteral exclamation marks while unquoted and with some interactive shells, they would expand to the last command put in the history
  • '*' is a litteral asterisk, unquoted it would be replaced by the list of non hidden filenames in the current directory.

As neither the POSIX standard nor the mainstream shells (sh (Bourne), ksh, bash, ash, dash, zsh, csh, tcsh) expand {} to something else, the quotes are not required.

However, there is an exotic shell, named fish, which happen to expand {} as an empty string, e.g.:

> ps -p %self
  PID TTY          TIME CMD
 5247 pts/1    00:00:00 fish
> echo a {} b '{}'
a  b {}

That is probably the reason why GNU find documentation suggest to protect {} against interpretation with quotes or backslashes.

9

For most users (particularly those using POSIX shells), there’s no difference.

According to the Example section of the man page for GNU find:

Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation.

I think the author(s) of the GNU man page are erring on the side of caution but I note that not all the examples in their man page quote the braces. These examples from the official GNU find documentation also omit the quoting.

In the examples from the POSIX / Single UNIX Specification the braces are not quoted when used with the -exec option.

With a POSIX shell, parameter expansion only occurs when there are special parameters enclosed within the braces – but not with empty braces.

The Bash shell includes brace expansion as a (non-portable) feature, but such patterns are only expanded when a comma or dots are included within the braces. Bash also uses braces for command grouping, but this doesn’t occur unless there actually is a group of commands within the brace.

Finally, I tried running find -exec ls -l {} \; in sh, dash and tcsh but none of these shells expanded the {} into anything else. As others have pointed out, the fish shell treats {} specially but this is not a POSIX shell (which its creators and users consider to be an advantage). It does no harm to quote the braces but lazy typists who don’t use the fish shell shouldn’t feel guilty about omitting them.

  • they are not erring, they are trying to make sure people use the correct way (ie use '{}' instead of {} ) so that their shell send {} to the find command without interpreting it (as mentionned above by @Charles-Duffy, if you happen to use fish, it will interpret {} but not '{}', so you need to use the latter on that shell (and on several others!). Therefore, always use '{}' to avoid being bitten by the ambiguity of {} – Olivier Dulac Nov 5 '15 at 13:59
6

This depends on your shell's syntax. When in doubt, echo it!

Run this

echo '{}'

and this.

echo {}

If they produce the same output, then the answer for your shell is yes. As others have noted, it will at least be yes in bash and no in fish. The output, is what you should consult a given command's manpage for.


If you want to get handy, you can even prefix echo to a whole command line, to see the actual command, with all its arguments, that your shell would actually invoke. Beware though, that the list comprising the command plus arguments is a true array of strings, each possibly empty or with whitespace, yet echo prints it ambiguously as a space separated list.

As can be verified with this slightly more verbose echo command (showing guillemet-quoted arguments),

#!/bin/sh
for a in "$@"; do
    printf '«%s» ' "$a"
done
echo ''

typing this on the command line,

find 'My Documents and Settings' -type f -exec file {} \;

means this to bash:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «{}» «;»

and this in fish:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «» «;»

As a general advice, it never hurts to quote.

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.