12

The find command seems to differ from other Unix commands.

Why is there the empty curly brackets and a backward flash at the end of the following command?

find * -perm 777 -exec chmod 770 {} \;

I found one reason for the curly brackets but not for the backward flash.

The curly brackets are apparently for the path

Same as -exec, except that ``{}'' is replaced with as many pathnames as possible for each invocation of utility

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697
  • 3
    The braces also let you run commands that don't expect (or require) the file name to be the last argument. You can use the braces to insert the file name wherever you want, even as the name of the program to execute! – Rob Kennedy Mar 22 '09 at 00:55
  • 1
    possible duplicate of [Simple unix command, what is the {} and \; for](http://stackoverflow.com/questions/447048/simple-unix-command-what-is-the-and-for) – kenorb Oct 18 '14 at 12:26

4 Answers4

16

The -exec command may be followed by any number of arguments that make up the command that is to be executed for each file found. There needs to be some way to identify the last argument. This is what \; does. Note that other things may follow after the -exec switch:

find euler/ -iname "*.c*" -exec echo {} \; -or -iname "*.py" -exec echo {} \;

(This finds all c-files and python files in the euler directory.)

The reason that exec does not require the full command to be inside quotes, is that this would require escaping a lot of quotes inside the command, in most circumstances.

Stephan202
  • 59,965
  • 13
  • 127
  • 133
7

The string {} in find is replaced by the pathname of the current file.

The semicolon is used for terminating the shell command invoked by find utility.

It needs to be escaped, or quoted, so it won't be interpreted by the shell, because ; is one of the special characters used by shell (list operators).

See also: Why are the backslash and semicolon required with the find command's -exec option?

Community
  • 1
  • 1
kenorb
  • 155,785
  • 88
  • 678
  • 743
3

The (escaped) semicolon is needed so that "find" can tell where the arguments to the exec'd program end (if there are any) and additional arguments to "find" begin.

nobody
  • 19,814
  • 17
  • 56
  • 77
1

I'd recommend that you instead do that as

find . -perm 777 -print0 | xargs -0 chmod 770

"xargs" says to take the results of the find and feed it 20 at a time to the following command.

Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
  • man xargs (of version 4.4.0) doesn't mention the number 20. This behaviour can be enforced though, by calling xargs with -n20. – Stephan202 Mar 22 '09 at 00:57
  • "20 at a time" was sort of a average. It's really however many as it thinks can fit in a normal command line, which I think is 512 bytes long in POSIX. – Paul Tomblin Mar 22 '09 at 01:10
  • The byte limit is LINE_MAX, for which I'm finding the common definition to be 2048. – Rob Kennedy Mar 22 '09 at 01:17