I'm trying to run the following command:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' +

This is returning an error:

find: missing argument to -exec

I can't see what's wrong with this command, as it seems to match the man page:

-exec command {} +

This variant of the -exec option runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invoca- tions of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of '{}' is allowed within the command. The command is executed in the starting directory.

I also tried:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' '{}' +
find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar '{}' +
find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar '{}' +
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
  • Have you tried escaping the + at the end? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
    – jayhendren
    May 7, 2014 at 21:37
  • 4
    You may be using an old version of GNU find. Though the -exec cmd {} + variant is POSIX and has been available since the 80s, GNU find only added it (relatively) recently (2005). What does find --version tell you? May 7, 2014 at 21:43
  • 3
    @Koveras, that would be it then. -exec {} + was added in 4.2.12 in 2005. In older GNU finds, you can use the (non-POSIX) -print0 | xargs -r0 to get something similar. 4.1 is from 1994. May 7, 2014 at 21:47
  • 1
    JRFerguson pointed out (in an answer that has been deleted) that the -name pattern arguments should be quoted: -name "*.c" -o -name "*.h".  This is true, although it’s unrelated to the -exec error.  You’ll notice that all the other answers put the wildcards into quotes, although only Gilles mentions it.  … (Cont’d) Mar 18, 2019 at 20:32
  • 1
    (Cont’d) … jlliagre’s answer collapses the name expression to -name "*.[ch]" without explanation.  This has the benefits of simplifying the command line and, specifically, eliminating the -o.  Find expressions involving -o are hard to get right.  Yours is wrong; if your command is fixed so that it doesn’t error out (as in Gilles’s answer), it will run grep only on the .h files.  You need to do '(' -name '*.c' -o -name '*.h' ')'. Mar 18, 2019 at 20:32

5 Answers 5


There was several issues with your attempts, including backticks used instead of quotes (removed in later edits to the question), missing quotes where they are required, extra quotes where they are useless, missing parentheses to group -o clauses, and different implementations of findused (see the comments and chat for details).

Anyway, the command can be simplified like this:

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} +

or, should you use an archaic GNU find version, this should always work:

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} \;
  • Oops, they were meant to be quotes not backticks. May 7, 2014 at 21:21
  • Quotes would be useless as {} has no specific meaning to the shell.
    – jlliagre
    May 7, 2014 at 21:26
  • From find man pages: "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." May 7, 2014 at 21:29
  • 1
    I indeed read that in the manual page but the fact is there is no shell I'm aware of that requires quoting the curly braces. What shell are you using ?
    – jlliagre
    May 7, 2014 at 21:37
  • bash. With or without the quotes I get the error anyways. May 7, 2014 at 21:38

“missing argument to -exec” usually means that the argument to -exec is missing its terminator. The terminator must either be an argument containing just the character ; (which needs to be quoted in a shell command, so it's typically written \; or ';'), or two successive arguments containing {} and +.

Stephane Chazelas has identified that you're using an older version of GNU find which doesn't support -exec … {} +, only -exec {} \;. Although GNU was a late adopter of -exec … {} +, I do recommend that you get a less antique tool suite (such as Cygwin, which includes git and a whole lot more, or GNUwin32, which lacks git but doesn't have the bad-employee-trying-to-use-linux-but-we-impose-windows vibe that Cygwin gives). This feature was added in version 4.2.12, over 9 years ago (it was the last identified feature to make GNU find POSIX-compliant).

If you want to stick to an older GNU find, you can use -print0 with xargs -0 to get a similar functionality: grouped command execution, supporting arbitrary file names.

find a/folder b/folder -name '*.c' -o -name '*.h' -print0 | xargs -0 grep -I foobar /dev/null

Always quote the wildcards on the find command line. Otherwise, if you happen to run this command from a directory containing .c files, the unquoted *.c would be expanded to the list of .c files in the current directory.

Adding /dev/null to the grep command line is a trick to ensure that grep will always print the file name, even if find happens to find a single match. With GNU find, another method is to pass the option -H.

  • 1
    What do you mean by bad-employee-trying-to-use-linux-but-we-impose-windows vibe that cygwin gives? May 16, 2014 at 20:36
  • GNUwin32 doesn't have expect :( May 17, 2014 at 16:18
  • See my comment(s) on the question. Mar 18, 2019 at 20:33
  • The quotes around the semi worked from within a package.json script.
    – bvj
    Nov 12, 2019 at 2:15
  • Eight years later I finally understand what he meant by the bad employee trying to use linux quote. Jul 14, 2022 at 16:27

If a command such as

find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar {} +

returns error

find: missing argument to -exec

the probable cause is too old GNU find which does not support syntax -exec mycommand {} +. In that case low performance replacement is to run -exec mycommand {} \; which will run the mycommand once for every found target instead of collecting multiple targets and running the mycommand just once.

However, GNU find does not support e.g.

find . -type f -and -name "*.ttf" -exec cp {} ~/.fonts +

because GNU find supports only literal combination {} + instead of more generic {} additional parameters +. Note that there cannot be anything between the braces and the + character. If you try this, you will get the same error:

find: missing argument to -exec

The workaround is to use syntax {} additional parameters \; which does work but will execute the command once for every found target. If you need more performance with GNU find you have to write a wrapper script that can append additional parameters to the arguments given. Something like

exec mycommand "$@" additional parameters

should be good enough. Or, if you do not want to create temporary file, you can use one-liner to change order of parameters like this:

find . -type f -and -name "*.ttf" -exec bash -c 'mycommand "$@" extra arguments' {} +

which will execute mycommand {list of ttf files} extra arguments. Note that you may need to double escape special characters for the bash after the -c flag.

  • (1) The part of the above that actually answers the question was already given by other people. (2) What you are describing is not a flaw or deficiency in GNU find, but the correct behavior specified by POSIX. Mar 18, 2019 at 20:03
  • 4
    +1 Finally, someone who answers why additional parameters don't work! It seems like a deficiency in the POSIX definition.
    – Jonathan
    Jul 11, 2019 at 18:29
  • 3
    If you've GNU find you've probably got GNU cp. In this case you could find ... -exec cp --target-directory ~/.fonts {} + to keep the {} at the end of the execution string. Aug 9, 2019 at 7:51
  • Yes, POSIX requires -exec ... {} + to work but it doesn't say that -exec ... {} ... + shouldn't work, too. As GNU tools have all kinds of extensions to POSIX stuff, this would have been a simple extension to make. The sad part is that GNU find uses the exact same error message for totally missing the support for {} + and for not supporting {} ... + syntax. Aug 7, 2022 at 9:59

find . -type f -perm 0777 -exec chmod 644 {}\;

got error find: missing argument to ``-exec'.

Adding space between {} and \ fixed it:

find . -type f -perm 0777 -print -exec chmod 644 {} \;

  • 1
    There is no such issue in the find command in the question at hand.
    – Kusalananda
    Mar 18, 2019 at 18:59
  • In Question it is not , fine, that I understood , but problem is same "find: missing argument to ``-exec'" , Problem can be occur from different-2 reason, I answered because I saw same problem statement.
    – ShreePool
    Mar 20, 2019 at 7:38
  • @Kusalananda good grief, the noob provided a solution for the reported error which is stated by the OP in both the title and body of the question.
    – bvj
    Apr 27, 2019 at 0:41
  • @bvj The question explicitly deals with the + form of the -exec option to find. This answer is correcting a problem that the user asking the question does not have.
    – Kusalananda
    Apr 27, 2019 at 6:01

I had my share of headaches with the exec syntax in the past. most days now I prefer the nicer bash syntax:

for f in `find a/folder b/folder -name "*.[ch]"`; do grep -I foobar $f; done

It has some limitations when you want to treat the files as a group, as each is evaluated serially, but you can pipe the output elsewhere just fine

  • 1
    While this tends to work it is significantly less useful than the pure-find version because it cannot handle files with whitespace in the name correctly. May 8, 2014 at 3:35
  • 6
    No, don't do this. This breaks as soon as the files contain spaces and other “weird” characters. This is also more complex and slower than find … -exec … \;, so there's no reason to use this even if you know that your file names are tame. May 8, 2014 at 3:44
  • this was helpful for my situation where I needed to run multiple lines of logic based on the file names (like removing chars, making directories and then moving the files). Trying to get find to do multiple things in one exec was too much of a headache for the 5 minutes I wanted to spend on this. My file names were tame and this solved my problem :)
    – gMale
    May 24, 2019 at 21:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .