Re: find -exec util {} arg + confusion
On Sat, 21 Nov 2020 17:02:05 +0100, Alexander Hall wrote: > So this is it. Any other objections? OK? OK millert@ - todd
Re: find -exec util {} arg + confusion
On Tue, Nov 17, 2020 at 01:11:42PM +0100, Paul de Weerd wrote: > On Tue, Nov 17, 2020 at 01:06:05AM +0100, Alexander Hall wrote: ... > | The more I read and think about it, I feel the original error message is > | actually correct in that there is no terminating ";" or "+", since the > | required condition for it is not fullfilled... > > I still think the error is confusing for the user who, familiar with > 'find -exec command {} arg \;', might assume the same would work for +. > Now, your diff seems like a better approach, given your argument. So this is it. Any other objections? OK? /Alexander Index: function.c === RCS file: /cvs/src/usr.bin/find/function.c,v retrieving revision 1.49 diff -u -p -r1.49 function.c --- function.c 9 Apr 2020 15:07:49 - 1.49 +++ function.c 21 Nov 2020 15:58:40 - @@ -564,7 +564,7 @@ c_exec(char *unused, char ***argvp, int */ for (ap = argv = *argvp, brace = 0;; ++ap) { if (!*ap) - errx(1, "%s: no terminating \";\" or \"+\"", + errx(1, "%s: no terminating \";\" or \"{} +\"", isok ? "-ok" : "-exec"); lastbrace = brace; brace = 0;
Re: find -exec util {} arg + confusion
On Mon, Nov 16, 2020 at 09:15:11AM +0100, Paul de Weerd wrote: > Hi Andreas, > > On Mon, Nov 16, 2020 at 08:53:36AM +0100, Andreas Kusalananda Kähäri wrote: > | On Thu, Nov 12, 2020 at 08:51:22PM +0100, Paul de Weerd wrote: > | > Hi all, > | > > | > I misread find(1) and did: > | > > | > [weerdpom] $ find path/to/cam -name \*.JPG -exec cp {} path/to/store + > | > find: -exec no terminating ";" or "+" > | > | Not really what you're asking for, but... > | > | What you seem to want to do can be done with > | > | find path/to/cam -name '*.JPG' -exec sh -c 'cp "$@" path/to/store' sh > {} + > > Thanks, I've solved this in the past with small scripts in my homedir > or going to `find | xargs -J`. I'll add your suggestion to my list. > > | Or, with GNU coreutils installed, > | > | find path/to/cam -name '*.JPG' -exec gcp -t path/to/store {} + > > Ugh, installing GNU stuff for something like this... :) Besides, the > problem is more generic than just cp(1). Do all GNU tools that (by > default) have the target argument as the last argument support -t? I > mean, I know cp, mv and ln do, but do they all? > That was just given as a suggestion for *if* you happened to have coreutils installed. Personally, I would opt for the "-exec sh -c" variant as it's portable to any sh shell and find/cp implementation (I'm often working on several different Unices). The coreutils' info documentation says that the non-standard convenience option -t (or --target-directory) is implemented for cp, install, ln, and mv. -- Andreas (Kusalananda) Kähäri SciLifeLab, NBIS, ICM Uppsala University, Sweden .
Re: find -exec util {} arg + confusion
On Thu, Nov 19, 2020 at 03:26:28PM -0800, Jordan Geoghegan wrote: > > > On 11/16/20 12:15 AM, Paul de Weerd wrote: > > Hi Andreas, > > > > On Mon, Nov 16, 2020 at 08:53:36AM +0100, Andreas Kusalananda Kähäri wrote: > > | On Thu, Nov 12, 2020 at 08:51:22PM +0100, Paul de Weerd wrote: > > | > Hi all, > > | > > > | > I misread find(1) and did: > > | > > > | > [weerdpom] $ find path/to/cam -name \*.JPG -exec cp {} path/to/store + > > | > find: -exec no terminating ";" or "+" > > | > > | Not really what you're asking for, but... > > | > > | What you seem to want to do can be done with > > | > > | find path/to/cam -name '*.JPG' -exec sh -c 'cp "$@" path/to/store' sh > > {} + > > > > Thanks, I've solved this in the past with small scripts in my homedir > > or going to `find | xargs -J`. I'll add your suggestion to my list. > > > > | Or, with GNU coreutils installed, > > | > > | find path/to/cam -name '*.JPG' -exec gcp -t path/to/store {} + > > > > Ugh, installing GNU stuff for something like this... :) Besides, the > > problem is more generic than just cp(1). Do all GNU tools that (by > > default) have the target argument as the last argument support -t? I > > mean, I know cp, mv and ln do, but do they all? > > > > | I quite like Alexander's proposed smaller diff. > > > > Making it more clear to the user that + must follow {} is the thing > > I'd like to achieve, so yeah :) No strong feelings over his vs my > > diff. > > > > Cheers, > > > > Paul > > > > Hi Paul, > > I've stumbled on this issue a number of times myself. The easiest workaround > I've found is to do something like this: > > find /tmp/1 -type f -name "*" -print0 | xargs -0 -I{} cp {} /tmp/2/ > > No GNU stuff needed. This would execute cp once for each found name rather than for batches of found names. Also, your -name test is a no-op as it matches every name. -- Andreas (Kusalananda) Kähäri SciLifeLab, NBIS, ICM Uppsala University, Sweden .
Re: find -exec util {} arg + confusion
On 11/16/20 12:15 AM, Paul de Weerd wrote: Hi Andreas, On Mon, Nov 16, 2020 at 08:53:36AM +0100, Andreas Kusalananda Kähäri wrote: | On Thu, Nov 12, 2020 at 08:51:22PM +0100, Paul de Weerd wrote: | > Hi all, | > | > I misread find(1) and did: | > | > [weerdpom] $ find path/to/cam -name \*.JPG -exec cp {} path/to/store + | > find: -exec no terminating ";" or "+" | | Not really what you're asking for, but... | | What you seem to want to do can be done with | | find path/to/cam -name '*.JPG' -exec sh -c 'cp "$@" path/to/store' sh {} + Thanks, I've solved this in the past with small scripts in my homedir or going to `find | xargs -J`. I'll add your suggestion to my list. | Or, with GNU coreutils installed, | | find path/to/cam -name '*.JPG' -exec gcp -t path/to/store {} + Ugh, installing GNU stuff for something like this... :) Besides, the problem is more generic than just cp(1). Do all GNU tools that (by default) have the target argument as the last argument support -t? I mean, I know cp, mv and ln do, but do they all? | I quite like Alexander's proposed smaller diff. Making it more clear to the user that + must follow {} is the thing I'd like to achieve, so yeah :) No strong feelings over his vs my diff. Cheers, Paul Hi Paul, I've stumbled on this issue a number of times myself. The easiest workaround I've found is to do something like this: find /tmp/1 -type f -name "*" -print0 | xargs -0 -I{} cp {} /tmp/2/ No GNU stuff needed. Regards, Jordan
Re: find -exec util {} arg + confusion
On November 17, 2020 1:11:42 PM GMT+01:00, Paul de Weerd wrote: >On Tue, Nov 17, 2020 at 01:06:05AM +0100, Alexander Hall wrote: >| On Mon, Nov 16, 2020 at 09:04:53AM +0100, Paul de Weerd wrote: >| > Hi Alexander, >| > >| > On Sun, Nov 15, 2020 at 10:22:32PM +0100, Alexander Hall wrote: >| > | I googled for "POSIX find", and hit this: >| > | >| > | >https://pubs.opengroup.org/onlinepubs/009695399/utilities/find.html >| > | >| > | => "Only a plus sign that follows an argument containing the two >| > | characters "{}" shall punctuate the end of the primary >expression. >| > | Other uses of the plus sign shall not be treated as special." >| > >| > Yep, I also found that when looking into this. It's unforunate, as >it >| > implies you can't use `-exec {} ... +` with e.g. ln, mv or cp, but >oh >| > well. >| > >| > (also, nitpicking, 'an argument containing the two characters "{}"' >| > includes an argument like "hh}hh{hh", which I'm pretty sure is not >| > what they mean) >| > >| > | What you do in your diff is exactly that, treating it special. >| > >| > I'm not sure I agree. I make sure I do not treat it special unless >|^^ >| > it's at the end of the argument to 'exec'. Can you elaborate on >what >| ^ >| > you mean here? >| >| If it is not following {}, then it should not be treated as such. You >| are assuming (or guessing) it was meant to be that special '+'. >| >| Carefully crafted example of failing quoting of ';': >| >| $ obj/find . -exec echo + ;# Just print a '+' for every entry >| find: -exec: "+" should follow {} > >In this case, I would say the error is correct: the + *is* at the end >of the argument to exec, and for -exec to work with +, it should >follow {}. > >Since you failed to escape the semi-colon, the shell (not find) >discards it (uses it to separate find from the next command), so find >never sees the ';', you're actually doing `find . -exec echo +`; the >plus doesn't follow the requisite {}. 1. The failed escaping of ";" was intentional, to hint that the intent really was not to use "+" as the delimiter. 2. A "+" not following a "{}" is by itself no indication that it was intended to end the -exec part. You are making assumptions, which in the case above would be wrong. Thus, the only thing we can know for sure is that there just simply is no terminating ";" or "+". I'd be fine with changing the "+" to "{} +" though. I did try separating them into "{}" "+" to not indicate they should be one single argument, but I still believe the former is easier on the eye and gives a good enough hint. > >I could change the diff to see if there is no {} at all (as in your >carefully crafted example), and change the output based on that again. Not sure exactly what you mean, but I think you'd just be assuming again. >However, using the diff that you proposed earlier in this thread (that >results in 'no terminating ";" or "{} +"') is probably the best way >forward (less code, still clear what the issue is). Yeah. I strongly agree. /Alexander > >| The more I read and think about it, I feel the original error message >is >| actually correct in that there is no terminating ";" or "+", since >the >| required condition for it is not fullfilled... > >I still think the error is confusing for the user who, familiar with >'find -exec command {} arg \;', might assume the same would work for +. >Now, your diff seems like a better approach, given your argument. > >Paul
Re: find -exec util {} arg + confusion
On Tue, Nov 17, 2020 at 01:06:05AM +0100, Alexander Hall wrote: | On Mon, Nov 16, 2020 at 09:04:53AM +0100, Paul de Weerd wrote: | > Hi Alexander, | > | > On Sun, Nov 15, 2020 at 10:22:32PM +0100, Alexander Hall wrote: | > | I googled for "POSIX find", and hit this: | > | | > | https://pubs.opengroup.org/onlinepubs/009695399/utilities/find.html | > | | > | => "Only a plus sign that follows an argument containing the two | > | characters "{}" shall punctuate the end of the primary expression. | > | Other uses of the plus sign shall not be treated as special." | > | > Yep, I also found that when looking into this. It's unforunate, as it | > implies you can't use `-exec {} ... +` with e.g. ln, mv or cp, but oh | > well. | > | > (also, nitpicking, 'an argument containing the two characters "{}"' | > includes an argument like "hh}hh{hh", which I'm pretty sure is not | > what they mean) | > | > | What you do in your diff is exactly that, treating it special. | > | > I'm not sure I agree. I make sure I do not treat it special unless |^^ | > it's at the end of the argument to 'exec'. Can you elaborate on what | ^ | > you mean here? | | If it is not following {}, then it should not be treated as such. You | are assuming (or guessing) it was meant to be that special '+'. | | Carefully crafted example of failing quoting of ';': | | $ obj/find . -exec echo + ;# Just print a '+' for every entry | find: -exec: "+" should follow {} In this case, I would say the error is correct: the + *is* at the end of the argument to exec, and for -exec to work with +, it should follow {}. Since you failed to escape the semi-colon, the shell (not find) discards it (uses it to separate find from the next command), so find never sees the ';', you're actually doing `find . -exec echo +`; the plus doesn't follow the requisite {}. I could change the diff to see if there is no {} at all (as in your carefully crafted example), and change the output based on that again. However, using the diff that you proposed earlier in this thread (that results in 'no terminating ";" or "{} +"') is probably the best way forward (less code, still clear what the issue is). | The more I read and think about it, I feel the original error message is | actually correct in that there is no terminating ";" or "+", since the | required condition for it is not fullfilled... I still think the error is confusing for the user who, familiar with 'find -exec command {} arg \;', might assume the same would work for +. Now, your diff seems like a better approach, given your argument. Paul -- >[<++>-]<+++.>+++[<-->-]<.>+++[<+ +++>-]<.>++[<>-]<+.--.[-] http://www.weirdnet.nl/
Re: find -exec util {} arg + confusion
On Mon, Nov 16, 2020 at 09:04:53AM +0100, Paul de Weerd wrote: > Hi Alexander, > > On Sun, Nov 15, 2020 at 10:22:32PM +0100, Alexander Hall wrote: > | I googled for "POSIX find", and hit this: > | > | https://pubs.opengroup.org/onlinepubs/009695399/utilities/find.html > | > | => "Only a plus sign that follows an argument containing the two > | characters "{}" shall punctuate the end of the primary expression. > | Other uses of the plus sign shall not be treated as special." > > Yep, I also found that when looking into this. It's unforunate, as it > implies you can't use `-exec {} ... +` with e.g. ln, mv or cp, but oh > well. > > (also, nitpicking, 'an argument containing the two characters "{}"' > includes an argument like "hh}hh{hh", which I'm pretty sure is not > what they mean) > > | What you do in your diff is exactly that, treating it special. > > I'm not sure I agree. I make sure I do not treat it special unless ^^ > it's at the end of the argument to 'exec'. Can you elaborate on what ^ > you mean here? If it is not following {}, then it should not be treated as such. You are assuming (or guessing) it was meant to be that special '+'. Carefully crafted example of failing quoting of ';': $ obj/find . -exec echo + ;# Just print a '+' for every entry find: -exec: "+" should follow {} The more I read and think about it, I feel the original error message is actually correct in that there is no terminating ";" or "+", since the required condition for it is not fullfilled... /Alexander > > Thanks! > > Paul > > -- > >[<++>-]<+++.>+++[<-->-]<.>+++[<+ > +++>-]<.>++[<>-]<+.--.[-] > http://www.weirdnet.nl/ >
Re: find -exec util {} arg + confusion
Hi Andreas, On Mon, Nov 16, 2020 at 08:53:36AM +0100, Andreas Kusalananda Kähäri wrote: | On Thu, Nov 12, 2020 at 08:51:22PM +0100, Paul de Weerd wrote: | > Hi all, | > | > I misread find(1) and did: | > | > [weerdpom] $ find path/to/cam -name \*.JPG -exec cp {} path/to/store + | > find: -exec no terminating ";" or "+" | | Not really what you're asking for, but... | | What you seem to want to do can be done with | | find path/to/cam -name '*.JPG' -exec sh -c 'cp "$@" path/to/store' sh {} + Thanks, I've solved this in the past with small scripts in my homedir or going to `find | xargs -J`. I'll add your suggestion to my list. | Or, with GNU coreutils installed, | | find path/to/cam -name '*.JPG' -exec gcp -t path/to/store {} + Ugh, installing GNU stuff for something like this... :) Besides, the problem is more generic than just cp(1). Do all GNU tools that (by default) have the target argument as the last argument support -t? I mean, I know cp, mv and ln do, but do they all? | I quite like Alexander's proposed smaller diff. Making it more clear to the user that + must follow {} is the thing I'd like to achieve, so yeah :) No strong feelings over his vs my diff. Cheers, Paul -- >[<++>-]<+++.>+++[<-->-]<.>+++[<+ +++>-]<.>++[<>-]<+.--.[-] http://www.weirdnet.nl/
Re: find -exec util {} arg + confusion
Hi Alexander, On Sun, Nov 15, 2020 at 10:22:32PM +0100, Alexander Hall wrote: | I googled for "POSIX find", and hit this: | | https://pubs.opengroup.org/onlinepubs/009695399/utilities/find.html | | => "Only a plus sign that follows an argument containing the two | characters "{}" shall punctuate the end of the primary expression. | Other uses of the plus sign shall not be treated as special." Yep, I also found that when looking into this. It's unforunate, as it implies you can't use `-exec {} ... +` with e.g. ln, mv or cp, but oh well. (also, nitpicking, 'an argument containing the two characters "{}"' includes an argument like "hh}hh{hh", which I'm pretty sure is not what they mean) | What you do in your diff is exactly that, treating it special. I'm not sure I agree. I make sure I do not treat it special unless it's at the end of the argument to 'exec'. Can you elaborate on what you mean here? Thanks! Paul -- >[<++>-]<+++.>+++[<-->-]<.>+++[<+ +++>-]<.>++[<>-]<+.--.[-] http://www.weirdnet.nl/
Re: find -exec util {} arg + confusion
On Thu, Nov 12, 2020 at 08:51:22PM +0100, Paul de Weerd wrote: > Hi all, > > I misread find(1) and did: > > [weerdpom] $ find path/to/cam -name \*.JPG -exec cp {} path/to/store + > find: -exec no terminating ";" or "+" Not really what you're asking for, but... What you seem to want to do can be done with find path/to/cam -name '*.JPG' -exec sh -c 'cp "$@" path/to/store' sh {} + Or, with GNU coreutils installed, find path/to/cam -name '*.JPG' -exec gcp -t path/to/store {} + > > That was somewhat surprising - there is a terminating "+". The error > really is that the "+" doesn't follow immediately after the "{}" > (which the manpage of course told me). Although it would be nice to > be able to use tools like cp and mv to -exec with +, I suspect there > to be dragons. So I'm proposing to change the error to point this out > to the unsuspecting user. > > Cheers, > > Paul 'WEiRD' de Weerd > > Index: function.c [cut] I quite like Alexander's proposed smaller diff. -- Andreas (Kusalananda) Kähäri SciLifeLab, NBIS, ICM Uppsala University, Sweden .
Re: find -exec util {} arg + confusion
On Sun, Nov 15, 2020 at 07:19:07PM +0100, Paul de Weerd wrote: > Hi all, > > It was pointed out to me off-list that I introduced a regression for > the case that has '+' as one of its arguments, e.g.: > > [weerd@pom] $ find /var/empty -exec echo + {} + > find: -exec: "+" should follow {} > > Updated diff fixes that case: > > [weerd@pom] $ ./find /var/empty -exec echo cp {} /tmp/dest + > find: -exec: "+" should follow {} > [weerd@pom] $ ./find /var/empty -exec echo + {} + > + /var/empty > > Any thoughts or concerns? Other regressions? > > Thanks, > > Paul I googled for "POSIX find", and hit this: https://pubs.opengroup.org/onlinepubs/009695399/utilities/find.html => "Only a plus sign that follows an argument containing the two characters "{}" shall punctuate the end of the primary expression. Other uses of the plus sign shall not be treated as special." What you do in your diff is exactly that, treating it special. The manual page could maybe be more exact, but otherwise sth like this could be enough (pardon the git diff, but you get the point). /Alexander diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c index 3d7f4963b1f..727f8dce43f 100644 --- a/usr.bin/find/function.c +++ b/usr.bin/find/function.c @@ -564,7 +564,7 @@ c_exec(char *unused, char ***argvp, int isok) */ for (ap = argv = *argvp, brace = 0;; ++ap) { if (!*ap) - errx(1, "%s: no terminating \";\" or \"+\"", + errx(1, "%s: no terminating \";\" or \"{} +\"", isok ? "-ok" : "-exec"); lastbrace = brace; brace = 0;
Re: find -exec util {} arg + confusion
Hi all, It was pointed out to me off-list that I introduced a regression for the case that has '+' as one of its arguments, e.g.: [weerd@pom] $ find /var/empty -exec echo + {} + find: -exec: "+" should follow {} Updated diff fixes that case: [weerd@pom] $ ./find /var/empty -exec echo cp {} /tmp/dest + find: -exec: "+" should follow {} [weerd@pom] $ ./find /var/empty -exec echo + {} + + /var/empty Any thoughts or concerns? Other regressions? Thanks, Paul Index: function.c === RCS file: /home/OpenBSD/cvs/src/usr.bin/find/function.c,v retrieving revision 1.49 diff -u -p -r1.49 function.c --- function.c 9 Apr 2020 15:07:49 - 1.49 +++ function.c 15 Nov 2020 18:12:04 - @@ -572,9 +572,14 @@ c_exec(char *unused, char ***argvp, int brace = 1; if (strcmp(*ap, ";") == 0) break; - if (strcmp(*ap, "+") == 0 && lastbrace) { - new->flags |= F_PLUSSET; - break; + if (strcmp(*ap, "+") == 0) { + if (lastbrace) { + new->flags |= F_PLUSSET; + break; + } else if (!*(ap+1)) { + errx(1, "%s: \"+\" should follow {}", + isok ? "-ok" : "-exec"); + } } } On Thu, Nov 12, 2020 at 08:51:22PM +0100, Paul de Weerd wrote: | Hi all, | | I misread find(1) and did: | | [weerdpom] $ find path/to/cam -name \*.JPG -exec cp {} path/to/store + | find: -exec no terminating ";" or "+" | | That was somewhat surprising - there is a terminating "+". The error | really is that the "+" doesn't follow immediately after the "{}" | (which the manpage of course told me). Although it would be nice to | be able to use tools like cp and mv to -exec with +, I suspect there | to be dragons. So I'm proposing to change the error to point this out | to the unsuspecting user. | | Cheers, | | Paul 'WEiRD' de Weerd | | Index: function.c | === | RCS file: /home/OpenBSD/cvs/src/usr.bin/find/function.c,v | retrieving revision 1.49 | diff -u -p -r1.49 function.c | --- function.c9 Apr 2020 15:07:49 - 1.49 | +++ function.c12 Nov 2020 19:42:49 - | @@ -572,9 +572,14 @@ c_exec(char *unused, char ***argvp, int | brace = 1; | if (strcmp(*ap, ";") == 0) | break; | - if (strcmp(*ap, "+") == 0 && lastbrace) { | - new->flags |= F_PLUSSET; | - break; | + if (strcmp(*ap, "+") == 0) { | + if (lastbrace) { | + new->flags |= F_PLUSSET; | + break; | + } else { | + errx(1, "%s: \"+\" should follow {}", | +isok ? "-ok" : "-exec"); | + } | } | } | | | -- | >[<++>-]<+++.>+++[<-->-]<.>+++[<+ | +++>-]<.>++[<>-]<+.--.[-] | http://www.weirdnet.nl/ | -- >[<++>-]<+++.>+++[<-->-]<.>+++[<+ +++>-]<.>++[<>-]<+.--.[-] http://www.weirdnet.nl/