Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The man page for gnu find states:

-exec command ;
    [...] The  string `{}'  is  replaced  by the current 
    file name being processed everywhere it occurs in the 
    arguments to the command, not just in arguments where 
    it is alone, as in some  versions  of  find.
    Both  of  these  constructions might need to be escaped 
    (with a `\') or quoted to protect them from expansion 
    by the shell. 

That's from the man to find (GNU findutils) 4.4.2.

Now I tested this with bash and dash, and both don't need to have the {} being masked. Here is a simple test:

find /etc -name "hosts" -exec md5sum {} \; 

Is there a shell, for which I really need to mask the braces? Note, that it doesn't depend upon whether the file found contains a blank (invoked from bash):

find ~ -maxdepth 1 -type d -name "U*" -exec ls -d {} \; 
/home/stefan/Ubuntu One

This changes if the found file is passed to a subshell:

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d {}' \; 
ls: cannot access /home/stefan/Ubuntu: No such file or directory
ls: cannot access One: No such file or directory

which can be solved by:

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "$0"' {} \;

in contrast to:

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "{}"' \; 
/home/stefan/Ubuntu One

but that's not what the man page is talking about, is it? So which shell treats {} in a different way?

share|improve this question

Summary: If there ever was a shell that expanded {}, it's really old legacy stuff by now.

In the Bourne shell and in POSIX-compliant shells, braces ({ and }) are ordinary characters (unlike ( and ) which are word delimiters like ; and &, and [ and ] which are globbing characters). The following strings are all supposed to be printed literally:

$ echo { } {} {foo,bar} {1..3}
{ } {} {foo,bar} {1..3}

A word consisting of a single brace is a reserved word, which is only special if it is the first word of a command.

Ksh implements brace expansion as an incompatible extension to the Bourne shell. This can be turned off with set +B. Bash emulates ksh in this respect. Zsh implements brace expansion as well; there it can be turned off with set +I or setopt ignore_braces or emulate sh. None of these shells expand {} in any case, even when it's a substring of a word (e.g. foo{}bar), due to the common use in arguments to find and xargs.

Single Unix v2 notes that

In some historical systems, the curly braces are treated as control operators. To assist in future standardisation activities, portable applications should avoid using unquoted braces to represent the characters themselves. It is possible that a future version of the ISO/IEC 9945-2:1993 standard may require that { and } be treated individually as control operators, although the token {} will probably be a special-case exemption from this because of the often-used find {} construct.

This note was dropped in subsequent versions of the standard; the examples for find have unquoted uses of {}, as do the examples for xargs. There may have been historical Bourne shells where {} had to be quoted, but they would be really old legacy systems by now.

The csh implementations I have at hand (OpenBSD 4.7, BSD csh on Debian, tcsh) all expand {foo} to foo but leave {} alone.

share|improve this answer
2@mress:3 B$ ls -d {te,pl}* platform-tools/ platforms/ temp/ 2@mress:4 B$ echo $BASH_VERSION 3.2.48(1)-release (hm, markup doesnt work in comments) – geekosaur Mar 5 '11 at 19:28
@geekosaur: Only a small subset of markdown works in comments. I don't know what you're trying to say. If this is about ksh et al's brace expansion, read my paragraph beginning with “Ksh implements brace expansion as an incompatible extension”. – Gilles Mar 5 '11 at 19:52
That was bash (see $BASH_VERSION). Brace expansion is very much alive and well. – geekosaur Mar 5 '11 at 20:18
That was the point. The {} syntax originated in csh, but {} expanded to the empty string. Newer shells recognize that that's nonsensical, but there are still some old cshs out there. – geekosaur Mar 5 '11 at 20:47
@geekosaur: Can you say which specific csh-version on which specific platform? I would prefer to test it myself (if it is possible on linux) or be assured, that the person testet it himself. – user unknown Mar 5 '11 at 22:30

The {} needs to be quoted in the fish shell.

$ fish -c 'echo find -exec {} \;'
find -exec  ;

And in the rc shell:

$ rc -c "echo find -exec {} ';'"
line 1: syntax error near '{'

Those are probably not the shells the authors of that GNU find documentation had in mind when they wrote that text since fish was first released in 2005 (while that text or similar was already there in 1994) and rc was not originally a Unix shell.

There are some rumors of some versions of csh requiring it. But it's hard to give credit to those since the first release of csh in 2BSD didn't. Here as tested in a PDP11 emulator:

# echo find -exec {} \;
find -exec {} ;

And the man page from 2BSD csh clearly states:

As a special case `{', `}' and `{}' are passed undisturbed.

So I would find it very strange if a subsequent version of csh or tcsh later broke that.

It could have been to work around some bugs in some versions. Still with that 2BSD csh (that's the same in 2.79BSD, 2.8BSD, 2.11BSD):

# csh -x
# echo foo {} bar
echo foo {} bar
foo {} bar
# echo `echo foo {} bar`
echo `echo foo {} bar`
echo foo {} bar
foo  bar

Quoting doesn't help though:

# echo `echo foo '{}' bar`
echo `echo foo '{}' bar`
echo foo {} bar
foo  bar

You could quote the whole command substitution:

# echo "`echo foo {} bar`"
echo `echo foo {} bar`
echo foo {} bar
foo {} bar

But that's passing one argument to that outer echo.

share|improve this answer

In a word, csh. bash and other modern shells recognize that the user probably isn't asking for a null brace expansion. (Modern csh is actually tcsh and may also handle {} sanely by now.)

share|improve this answer
Nice to hear, but I'm asking for the opposite, a shell for which doesn't handle it sanely. – user unknown Mar 5 '11 at 15:49
You're assuming that someone would go in and rip out the info page's reference to extra quoting just because Linux systems all have newer csh. Not everyone runs GNU utilities on Linux; in fact it's quite common to install them on older commercial Unix systems whose bundled commands are limited. (Replacing csh on those systems is less likely, because system scripts may rely on the idiosyncrasies of the original csh, and even if users were all configured to use a newer csh, root would almost certainly need to remain the bundled version.) – geekosaur Mar 5 '11 at 15:55
No. I'm in a debate with a guy who says, that in our wiki we should give the advice to use "{}" all the time, because the man page says so. And now I would like to know if there is a shell I'm not using, like ksh, zsh, tcsh, csh or XYZsh which I don't know, for which this claim is true, or whether I honestly can assume, that there isn't. If there are shells for different Unixes which need the "{}", that would be a fine explanation why the sentence is still in the man page, but not appropriate as advice for linux beginners. – user unknown Mar 5 '11 at 19:14
Now I'm wondering if pdksh does the right thing... although the correct answer to that is probably "real ksh is FOSS these days". – geekosaur Mar 5 '11 at 19:26
Pdksh, like mksh, ksh93, bash and zsh, only expands braces when there's a comma in between (or .. for ksh93, bash and zsh). Only (t)csh expands {foo} to foo, and even it leaves {} alone (at least on recent BSD's). – Gilles Mar 5 '11 at 20:42

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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