I'm trying to use find to echo 0 into some files, but apparently this only works with sh -c:
find /proc/sys/net/ipv6 -name accept_ra -exec sh -c 'echo 0 > {}' \;
But using sh -c with find -exec makes me feel very uneasy because I suspect quoting problems. I fiddled a bit with it and apparently my suspicions were justified:
My test setup:
martin@dogmeat ~ % cd findtest martin@dogmeat ~/findtest % echo one > file\ with\ spaces martin@dogmeat ~/findtest % echo two > file\ with\ \'single\ quotes\' martin@dogmeat ~/findtest % echo three > file\ with\ \"double\ quotes\" martin@dogmeat ~/findtest % ll insgesamt 12K -rw-rw-r-- 1 martin martin 6 Sep 17 12:01 file with "double quotes" -rw-rw-r-- 1 martin martin 4 Sep 17 12:01 file with 'single quotes' -rw-rw-r-- 1 martin martin 4 Sep 17 12:01 file with spacesUsing
find -execwithoutsh -cseems to work without problems - no quoting necessary here:martin@dogmeat ~ % find findtest -type f -exec cat {} \; one two threeBut when I'm using
sh -c{}seems to require some kind of quoting:martin@dogmeat ~ % LANG=C find findtest -type f -exec sh -c 'cat {}' \; cat: findtest/file: No such file or directory cat: with: No such file or directory cat: spaces: No such file or directory cat: findtest/file: No such file or directory cat: with: No such file or directory cat: single quotes: No such file or directory cat: findtest/file: No such file or directory cat: with: No such file or directory cat: double quotes: No such file or directoryDouble quotes work as long as no file name contains double quotes:
martin@dogmeat ~ % LANG=C find findtest -type f -exec sh -c 'cat "{}"' \; one two cat: findtest/file with double: No such file or directory cat: quotes: No such file or directorySingle quotes work as long as no file name contains single quotes:
martin@dogmeat ~ % LANG=C find findtest -type f -exec sh -c "cat '{}'" \; one cat: findtest/file with single: No such file or directory cat: quotes: No such file or directory three
I haven't found a solution that works in all cases. Is there something I'm overlooking, or is using sh -c in find -exec inherently unsafe?
shseems to be some kind of placeholder, it works too if replaced by_for example - very useful if you want to call bash internals:find /tmp -name 'fil*' -exec bash -c 'printf "%q\n" "$1"' _ {} \;. But does anybody know where this is documented? – Florian F Sep 17 '14 at 14:12$0(usually the name of the shell. You need to skip it in this scenario so it doesn't eat one of your normal positional arguments. The documentation for-cmentions this. – Etan Reisner Sep 17 '14 at 14:18findnot allowing that embedding? – Etan Reisner Sep 17 '14 at 14:20s/most/some/in your answer. – Etan Reisner Sep 17 '14 at 14:38shhas its pluses and minuses. It gives better error messages, but isn't quite as clear to people as a placeholder vs_, which would be common and very intuitive. – Sep 18 '14 at 00:04$0, and using_would deceive them into thinking it's a placeholder. And I can't see what's intuitive about_(it's even more cumbersome to type thanshon my British keyboard). If you want something shorter, use.. At least that suggests the.(source) command which would be slightly more appropriate for$0. – Stéphane Chazelas Sep 18 '14 at 08:37argv[0]. – phk Nov 01 '16 at 15:44argv[0]here, that's just the$0of the script. Sven's page is inaccurate here, arwon't make the shell enter a restricted mode as far as can tell andzshwon't change mode based on$0.(exec -a rksh ksh -c 'cd /')will run a restrictedksh, but notksh -c 'cd /' rksh). – Stéphane Chazelas Nov 01 '16 at 16:33findwith-exec sh -cand embedding{}in the shell code" ? – don_crissti Dec 23 '16 at 22:01_,-,--or the empty string is used for the shell's error messages" mean? Why does usinginline-shnot work in the example, given thatinline-shis not_,-,--or the empty string? – Tim Jun 08 '18 at 13:16