find: missing argument to `-exec' when using + form of find











up vote
3
down vote

favorite












I want to execute a command on the paths found with the find command and I want to use + to reduce the number of times the external command is launched.



Critically, the command has a fixed value final argument. Here's a concrete example with echo as the command, although in the real :



mkdir blah && cd blah
touch fooA
touch fooB
find . -name 'foo*' -exec echo {} second +


I would expect this to print:



./fooA ./fooB second


but instead I get the error find: missing argument to-exec'. I've tried all sorts of permutations to get it to work with +. Why isn't this working? It works find with the;` variant:



find . -name 'foo*' -exec echo {} second ;
./fooB second
./fooA second


... but that's not what I'm after.



find --version reports:



find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=0)


Here's an excerpt from the man pages covering the + and ; forms:



   -exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encoun‐
tered. 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. See the
EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched file. The command is executed in the starting direc‐
tory. There are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead.

-exec command {} +
This variant of the -exec action 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 invocations 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 com‐
mand lines. Only one instance of `{}' is allowed within the command. The command is executed in the starting directory.









share|improve this question
























  • What shell are you using?
    – roaima
    Mar 16 '15 at 23:59










  • According to the man page the -exec command expects the {} at the very end of the expression since it tries to concatenate the files found. Putting the second before the {} will work but, of course, that does not really help you. The error message is a little misleading.
    – Marcus Rickert
    Mar 17 '15 at 0:02










  • Where in the man do you see that? I included the man output on my system in question. For the ; form it is clear that multiple {} are allowed, implying they don't have to be at the end of the command. The + form says the command line is built by appending each selected file name at the end - but I read "the end" here as the end of the string which will ultimately be used to replace the {}. If it was always at the end, why use {}? The text Only one instance of {}' is allowed within the command` imlies that one instance can be anywhere (or else why not restrict it)?
    – BeeOnRope
    Mar 18 '15 at 23:48

















up vote
3
down vote

favorite












I want to execute a command on the paths found with the find command and I want to use + to reduce the number of times the external command is launched.



Critically, the command has a fixed value final argument. Here's a concrete example with echo as the command, although in the real :



mkdir blah && cd blah
touch fooA
touch fooB
find . -name 'foo*' -exec echo {} second +


I would expect this to print:



./fooA ./fooB second


but instead I get the error find: missing argument to-exec'. I've tried all sorts of permutations to get it to work with +. Why isn't this working? It works find with the;` variant:



find . -name 'foo*' -exec echo {} second ;
./fooB second
./fooA second


... but that's not what I'm after.



find --version reports:



find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=0)


Here's an excerpt from the man pages covering the + and ; forms:



   -exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encoun‐
tered. 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. See the
EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched file. The command is executed in the starting direc‐
tory. There are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead.

-exec command {} +
This variant of the -exec action 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 invocations 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 com‐
mand lines. Only one instance of `{}' is allowed within the command. The command is executed in the starting directory.









share|improve this question
























  • What shell are you using?
    – roaima
    Mar 16 '15 at 23:59










  • According to the man page the -exec command expects the {} at the very end of the expression since it tries to concatenate the files found. Putting the second before the {} will work but, of course, that does not really help you. The error message is a little misleading.
    – Marcus Rickert
    Mar 17 '15 at 0:02










  • Where in the man do you see that? I included the man output on my system in question. For the ; form it is clear that multiple {} are allowed, implying they don't have to be at the end of the command. The + form says the command line is built by appending each selected file name at the end - but I read "the end" here as the end of the string which will ultimately be used to replace the {}. If it was always at the end, why use {}? The text Only one instance of {}' is allowed within the command` imlies that one instance can be anywhere (or else why not restrict it)?
    – BeeOnRope
    Mar 18 '15 at 23:48















up vote
3
down vote

favorite









up vote
3
down vote

favorite











I want to execute a command on the paths found with the find command and I want to use + to reduce the number of times the external command is launched.



Critically, the command has a fixed value final argument. Here's a concrete example with echo as the command, although in the real :



mkdir blah && cd blah
touch fooA
touch fooB
find . -name 'foo*' -exec echo {} second +


I would expect this to print:



./fooA ./fooB second


but instead I get the error find: missing argument to-exec'. I've tried all sorts of permutations to get it to work with +. Why isn't this working? It works find with the;` variant:



find . -name 'foo*' -exec echo {} second ;
./fooB second
./fooA second


... but that's not what I'm after.



find --version reports:



find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=0)


Here's an excerpt from the man pages covering the + and ; forms:



   -exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encoun‐
tered. 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. See the
EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched file. The command is executed in the starting direc‐
tory. There are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead.

-exec command {} +
This variant of the -exec action 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 invocations 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 com‐
mand lines. Only one instance of `{}' is allowed within the command. The command is executed in the starting directory.









share|improve this question















I want to execute a command on the paths found with the find command and I want to use + to reduce the number of times the external command is launched.



Critically, the command has a fixed value final argument. Here's a concrete example with echo as the command, although in the real :



mkdir blah && cd blah
touch fooA
touch fooB
find . -name 'foo*' -exec echo {} second +


I would expect this to print:



./fooA ./fooB second


but instead I get the error find: missing argument to-exec'. I've tried all sorts of permutations to get it to work with +. Why isn't this working? It works find with the;` variant:



find . -name 'foo*' -exec echo {} second ;
./fooB second
./fooA second


... but that's not what I'm after.



find --version reports:



find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=0)


Here's an excerpt from the man pages covering the + and ; forms:



   -exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encoun‐
tered. 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. See the
EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched file. The command is executed in the starting direc‐
tory. There are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead.

-exec command {} +
This variant of the -exec action 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 invocations 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 com‐
mand lines. Only one instance of `{}' is allowed within the command. The command is executed in the starting directory.






linux find coreutils






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 18 '15 at 23:45

























asked Mar 16 '15 at 23:44









BeeOnRope

520619




520619












  • What shell are you using?
    – roaima
    Mar 16 '15 at 23:59










  • According to the man page the -exec command expects the {} at the very end of the expression since it tries to concatenate the files found. Putting the second before the {} will work but, of course, that does not really help you. The error message is a little misleading.
    – Marcus Rickert
    Mar 17 '15 at 0:02










  • Where in the man do you see that? I included the man output on my system in question. For the ; form it is clear that multiple {} are allowed, implying they don't have to be at the end of the command. The + form says the command line is built by appending each selected file name at the end - but I read "the end" here as the end of the string which will ultimately be used to replace the {}. If it was always at the end, why use {}? The text Only one instance of {}' is allowed within the command` imlies that one instance can be anywhere (or else why not restrict it)?
    – BeeOnRope
    Mar 18 '15 at 23:48




















  • What shell are you using?
    – roaima
    Mar 16 '15 at 23:59










  • According to the man page the -exec command expects the {} at the very end of the expression since it tries to concatenate the files found. Putting the second before the {} will work but, of course, that does not really help you. The error message is a little misleading.
    – Marcus Rickert
    Mar 17 '15 at 0:02










  • Where in the man do you see that? I included the man output on my system in question. For the ; form it is clear that multiple {} are allowed, implying they don't have to be at the end of the command. The + form says the command line is built by appending each selected file name at the end - but I read "the end" here as the end of the string which will ultimately be used to replace the {}. If it was always at the end, why use {}? The text Only one instance of {}' is allowed within the command` imlies that one instance can be anywhere (or else why not restrict it)?
    – BeeOnRope
    Mar 18 '15 at 23:48


















What shell are you using?
– roaima
Mar 16 '15 at 23:59




What shell are you using?
– roaima
Mar 16 '15 at 23:59












According to the man page the -exec command expects the {} at the very end of the expression since it tries to concatenate the files found. Putting the second before the {} will work but, of course, that does not really help you. The error message is a little misleading.
– Marcus Rickert
Mar 17 '15 at 0:02




According to the man page the -exec command expects the {} at the very end of the expression since it tries to concatenate the files found. Putting the second before the {} will work but, of course, that does not really help you. The error message is a little misleading.
– Marcus Rickert
Mar 17 '15 at 0:02












Where in the man do you see that? I included the man output on my system in question. For the ; form it is clear that multiple {} are allowed, implying they don't have to be at the end of the command. The + form says the command line is built by appending each selected file name at the end - but I read "the end" here as the end of the string which will ultimately be used to replace the {}. If it was always at the end, why use {}? The text Only one instance of {}' is allowed within the command` imlies that one instance can be anywhere (or else why not restrict it)?
– BeeOnRope
Mar 18 '15 at 23:48






Where in the man do you see that? I included the man output on my system in question. For the ; form it is clear that multiple {} are allowed, implying they don't have to be at the end of the command. The + form says the command line is built by appending each selected file name at the end - but I read "the end" here as the end of the string which will ultimately be used to replace the {}. If it was always at the end, why use {}? The text Only one instance of {}' is allowed within the command` imlies that one instance can be anywhere (or else why not restrict it)?
– BeeOnRope
Mar 18 '15 at 23:48












2 Answers
2






active

oldest

votes

















up vote
1
down vote













I couldn't find a solution with find -exec + or find | xargs, but GNU Parallel can do the job.



mkdir blah && cd blah
touch fooA
touch fooB
find . -name 'foo*' -print0 | parallel -0 -j1 -X echo {} second


Produces:



./fooA ./fooB second


Note, the -j1 option limits parallel to one job at a time, which is only used here in an attempt to reproduce the behavior that would have been expected from find -exec +.






share|improve this answer




























    up vote
    1
    down vote













    Here is a similar solution with find | xargs:



    find . -name 'foo*' -print0 | xargs -0 -n1 -I{} echo {} second





    share|improve this answer





















      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "3"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f890416%2ffind-missing-argument-to-exec-when-using-form-of-find%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      1
      down vote













      I couldn't find a solution with find -exec + or find | xargs, but GNU Parallel can do the job.



      mkdir blah && cd blah
      touch fooA
      touch fooB
      find . -name 'foo*' -print0 | parallel -0 -j1 -X echo {} second


      Produces:



      ./fooA ./fooB second


      Note, the -j1 option limits parallel to one job at a time, which is only used here in an attempt to reproduce the behavior that would have been expected from find -exec +.






      share|improve this answer

























        up vote
        1
        down vote













        I couldn't find a solution with find -exec + or find | xargs, but GNU Parallel can do the job.



        mkdir blah && cd blah
        touch fooA
        touch fooB
        find . -name 'foo*' -print0 | parallel -0 -j1 -X echo {} second


        Produces:



        ./fooA ./fooB second


        Note, the -j1 option limits parallel to one job at a time, which is only used here in an attempt to reproduce the behavior that would have been expected from find -exec +.






        share|improve this answer























          up vote
          1
          down vote










          up vote
          1
          down vote









          I couldn't find a solution with find -exec + or find | xargs, but GNU Parallel can do the job.



          mkdir blah && cd blah
          touch fooA
          touch fooB
          find . -name 'foo*' -print0 | parallel -0 -j1 -X echo {} second


          Produces:



          ./fooA ./fooB second


          Note, the -j1 option limits parallel to one job at a time, which is only used here in an attempt to reproduce the behavior that would have been expected from find -exec +.






          share|improve this answer












          I couldn't find a solution with find -exec + or find | xargs, but GNU Parallel can do the job.



          mkdir blah && cd blah
          touch fooA
          touch fooB
          find . -name 'foo*' -print0 | parallel -0 -j1 -X echo {} second


          Produces:



          ./fooA ./fooB second


          Note, the -j1 option limits parallel to one job at a time, which is only used here in an attempt to reproduce the behavior that would have been expected from find -exec +.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 17 '15 at 4:55









          zackse

          51237




          51237
























              up vote
              1
              down vote













              Here is a similar solution with find | xargs:



              find . -name 'foo*' -print0 | xargs -0 -n1 -I{} echo {} second





              share|improve this answer

























                up vote
                1
                down vote













                Here is a similar solution with find | xargs:



                find . -name 'foo*' -print0 | xargs -0 -n1 -I{} echo {} second





                share|improve this answer























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  Here is a similar solution with find | xargs:



                  find . -name 'foo*' -print0 | xargs -0 -n1 -I{} echo {} second





                  share|improve this answer












                  Here is a similar solution with find | xargs:



                  find . -name 'foo*' -print0 | xargs -0 -n1 -I{} echo {} second






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 20 at 22:09









                  7yl4r

                  1135




                  1135






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Super User!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f890416%2ffind-missing-argument-to-exec-when-using-form-of-find%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      QoS: MAC-Priority for clients behind a repeater

                      Ивакино (Тотемский район)

                      Can't locate Autom4te/ChannelDefs.pm in @INC (when it definitely is there)