Skip to main content
47 events
when toggle format what by license comment
Jul 24, 2024 at 15:35 comment added Praveen Lobo @Kusalananda Sure. If I'm not passing any or know exactly how many arguments & know to start at $0 at the risk of readability. Otherwise there will be unnecessary code to figure out the number of arguments. If anyone else is testing this, please note that with + you must have {} and it must appear by itself to avoid errors "find: missing argument to `-exec'" and "find: In ‘-exec ... {} +’ the ‘{}’ must appear by itself, but you specified <cmd>" respectively. At least in find (GNU findutils) 4.8.0
Jul 24, 2024 at 15:13 comment added Kusalananda @PraveenLobo Of course, you don't need to add that first sh argument after the inline script if you're not passing any arguments to the script. But if you do pass arguments and wants to use them in the script, then you'd better add a string (for example sh) for the $0 argument (not part of the $@ list), or what you think is your first argument will actually be the second.
Jul 24, 2024 at 15:08 comment added Praveen Lobo @Kusalananda Would you be so kind to give an example of that? I tried to by deliberately failing a command but I don't see any difference with or without sh. I suspect the scenario you mention is not as simple as failing a command. The only difference I see is when shell variables such as $#, $*, or $@ are involved along with + for many arguments.
Mar 7, 2024 at 17:23 comment added Kusalananda @Chris That string is used in error messages that the sh -c shell may produce. Making it the string sh or find-sh or some similar string is common to be able to distinguish diagnostic output from that sh -c shell invocation from any other diagnostic output that a script (or the utilities used in a script) might possibly produce.
Mar 7, 2024 at 15:52 comment added Chris If the final sh can be any text, or indeed any value, just to displace the rest to $1+, why is it almost always sh? I find using sh here confusing as it looks like a shell invocation, as if $0 must be an executable.
Aug 8, 2022 at 9:45 review Suggested edits
Aug 8, 2022 at 13:28
Apr 22, 2022 at 23:49 comment added Kusalananda @midnite You would need to use $1 in place of $name. Other than that, it would be functionally equivalent but would start sh -c once for each found name rather than batching found names and running sh -c as few times as possible.
Apr 22, 2022 at 23:43 comment added midnite Very nice answer. For the last example, is it the same if we use ; instead of + and without the for-loop? That is find . -type f -name '*.txt' -exec sh -c 'mv "$name" "${name%/*}/done-texts/${name##*/}.done"' sh {} ';'. What are the differences?
Mar 8, 2022 at 19:16 comment added Robin A. Meade Optimization: Reverse the order of the predicates -type f -name '*.txt' to be -name '*.txt' -type f. Doing so would avoid applying -type f "which potentially involves an extra expensive lstat() system call" when name does not match *.txt, per answer to a different question.
Feb 22, 2021 at 10:13 history edited Stéphane Chazelas CC BY-SA 4.0
added 321 characters in body
Jul 9, 2020 at 6:52 comment added Kusalananda @Atralb Yes, that would also have worked and had the same effect as the last piece of code, but instead of running mv in a loop, once per found file, you execute both sh and mv for each found file, which will be noticeably slower for large amounts of files.
Jul 8, 2020 at 22:58 comment added Atralb @Kusalananda Wouldn't your last example also work with this simpler command : find . -type f -name '*.txt' -exec sh -c "mv $1 $(dirname $1)/done-texts/$(basename $1).done" sh {} ';' ?
Dec 19, 2019 at 7:47 history edited Kusalananda CC BY-SA 4.0
added 61 characters in body
Jul 7, 2019 at 18:27 comment added bit @Kusalananda , I find my self in need of understanding the -exec and execdir options of find, so excuse me for commenting on an old answer but I have a question. In your example for -execdir, how are you guaranteeing that the subdirectory done-texts exist in the same directory where a .txt file is found? Or is your reasoning that -exec will exit with a non zero failure status when the subdirectory done-texts is not in the same directory as a .txt file meaning .txt files will only be moved by mv when the done-texts subdirectory is in the same directory as a .txt file?
Jun 7, 2019 at 19:21 history edited Kusalananda CC BY-SA 4.0
added 16 characters in body
Mar 16, 2019 at 21:47 history edited Kusalananda CC BY-SA 4.0
deleted 199 characters in body
Nov 1, 2018 at 13:59 history edited Kusalananda CC BY-SA 4.0
added 43 characters in body
Jul 7, 2018 at 12:06 history edited Kusalananda CC BY-SA 4.0
added 7 characters in body
Jul 7, 2018 at 8:55 history edited Kusalananda CC BY-SA 4.0
added 107 characters in body
Jul 7, 2018 at 8:36 history edited Kusalananda CC BY-SA 4.0
added 3669 characters in body
Jul 4, 2018 at 12:42 history edited Kusalananda CC BY-SA 4.0
added 18 characters in body
Jun 25, 2018 at 8:55 history edited Kusalananda CC BY-SA 4.0
deleted 12 characters in body
Jun 3, 2018 at 20:34 history edited Kusalananda CC BY-SA 4.0
added 6 characters in body
Jun 3, 2018 at 20:28 history edited Kusalananda CC BY-SA 4.0
added 134 characters in body
Jun 3, 2018 at 20:23 history edited Kusalananda CC BY-SA 4.0
added 134 characters in body
Jun 3, 2018 at 20:14 history edited Kusalananda CC BY-SA 4.0
added 10 characters in body
May 26, 2018 at 8:29 history edited Kusalananda CC BY-SA 4.0
added 54 characters in body
May 5, 2018 at 18:30 history edited Kusalananda CC BY-SA 4.0
added 2 characters in body
May 5, 2018 at 18:17 history edited Kusalananda CC BY-SA 4.0
deleted 16 characters in body
Apr 26, 2018 at 20:45 history edited Kusalananda CC BY-SA 3.0
added 81 characters in body
Sep 26, 2017 at 11:30 history edited Kusalananda CC BY-SA 3.0
added 34 characters in body
Sep 26, 2017 at 11:25 comment added Stéphane Chazelas You could clarify that all the find arguments after -exec and up to ; or + make up the command to execute along with its arguments, with each instance of a {} argument replaced with the current file (with ;), and {} as the last argument before + replaced with a list of files as separate arguments (in the {} + case). IOW -exec takes several arguments, terminated by a ; or {} +.
Sep 26, 2017 at 11:08 history edited Kusalananda CC BY-SA 3.0
deleted 32 characters in body
Sep 26, 2017 at 11:06 comment added Kusalananda @StéphaneChazelas I tried to not be too technical at the start. This is clarified (I hope) by the "footnote". I will adjust it to "external utility".
Sep 26, 2017 at 11:03 comment added Stéphane Chazelas Saying it's a shell command is wrong here, find -exec cmd arg \; doesn't invoke a shell to interpret a shell command line, it runs execlp("cmd", "arg") directly, not execlp("sh", "-c", "cmd arg") (for which the shell would end up doing the equivalent of execlp("cmd", "arg") if cmd was not builtin).
Sep 26, 2017 at 10:02 history edited Kusalananda CC BY-SA 3.0
added 13 characters in body
Sep 1, 2017 at 16:09 history edited Kusalananda CC BY-SA 3.0
added 291 characters in body
Sep 1, 2017 at 14:51 history edited Kusalananda CC BY-SA 3.0
added 6 characters in body
Sep 1, 2017 at 12:01 history edited Kusalananda CC BY-SA 3.0
added 105 characters in body
Sep 1, 2017 at 11:49 history edited Kusalananda CC BY-SA 3.0
added 9 characters in body
Sep 1, 2017 at 11:32 history edited Kusalananda CC BY-SA 3.0
added 181 characters in body
Sep 1, 2017 at 10:07 history edited Kusalananda CC BY-SA 3.0
added 17 characters in body
Sep 1, 2017 at 8:59 history edited Kusalananda CC BY-SA 3.0
added 917 characters in body
Sep 1, 2017 at 8:33 history edited Kusalananda CC BY-SA 3.0
added 38 characters in body
Sep 1, 2017 at 8:28 vote accept Zsolt Szilagy
Sep 1, 2017 at 8:26 history edited Kusalananda CC BY-SA 3.0
added 488 characters in body
Sep 1, 2017 at 8:18 history answered Kusalananda CC BY-SA 3.0