6 ms·
This is simply not true: $ mkdir '; echo woops' $ find . -type d -exec echo {} ';' . ./; echo woops As you can see 'woops' is never echoed. E
by neoteric 14y ago
This is simply not true:
$ mkdir '; echo woops'
$ find . -type d -exec echo {} ';'
.
./; echo woops
As you can see 'woops' is never echoed.
EDIT: The reason being the shell is never involved in this process, and the shell is what is responsible for splitting commands on semicolons/newlines.
- jcr 14y agoYou are assuming the exact versions of the shell and find programs that you use are the only ones that exist. It may not be a problem on your exact system, but it can be a problem elsewhere.
- neoteric 14y agoI am assuming a POSIX-compliant implementation of `find`. The shell is not involved. FWIW, your `find -print0`/`xargs -0` is not POSIX.
- jcr 14y agoSorry, I didn't see your 'EDIT' caveat when I responded --now that will teach me to reply too soon. ;-) Also, it seems I failed to be clear; I'm probably too tired I suppose. My point was there is plenty of ancient and buggy code out there. It could be "most", or even "many" modern unix variants have fixed a lot of the old bugs in find(1), but if you don't have the luxury of working on a current system, and your not allowed to upgrade it, then plenty bad things can happen due to invoking a shell, handling space, quote, and delimiter characters, and so forth. reference: $ uname -a OpenBSD alien.foo.test 5.1 GENERIC.MP#207 amd64 setup: $ mkdir test $ cd test $ touch file1 $ touch file2 $ touch file3 $ mkdir ';ls' bad: $ find . -type d -exec sh -c {} \; sh: ./: cannot execute - Is a directory ;ls file1 file2 file3 test.sh better: $ find . -type d -exec sh -ec {} \; sh: ./: cannot execute - Is a directory also bad: $ find . -type d -print0 | xargs -0 -r -n 1 -J % sh -c "%" sh: ./: cannot execute - Is a directory ;ls file1 file2 file3 test.sh better: $ find . -type d -print0 | xargs -0 -r -n 1 -x -J % sh -ec "%" sh: ./: cannot execute - Is a directory better; $ find . -type d -print0 | xargs -0 -r -J % sh -c "%" best: $ find . -type d -print0 | xargs -0 -r -J % sh -ec "%" POSIX is all great and wonderful in theory, but in practice it's no different than the bogus Java "write once, run anywhere" claim. If a system or utility claims to be POSIX compliant, then you're probably close, but you'll still need to do testing and debugging. At least some of the issues with find/xargs are mentioned in the following wikipedia article. It's probably more clear than I am right now. http://en.wikipedia.org/wiki/Xargs http://en.wikipedia.org/wiki/Xargs
- neoteric 14y agoThe contrived examples you've shown aren't examples of POSIX-incompatibility, or bugs in `find` at all. You've explicitly involved the shell. Of course trying to run every directory name as a shell command string is going to result in executed code! Your original argument was that given: find . -type d -exec chmod g+x {} ';' It is possible to force code execution of arbitrary commands given a carefully crafted directory name. The key difference in this case is that the shell is not involved _at all_. I challenge you to find an implementation of `find` that is broken in this way. As a side note, it is even possible to involve the shell in the picture in a safe way with `find`, without the use of `xargs` (and thus avoid the overhead of setting up a pipeline): find . -type d -exec sh -c 'chmod g+x "$1"' _ {} ';' (my contrived example is quite poor, though, since it does nothing but introduce unnecessary shell overhead) Modern (POSIX > 2001?) `find`'s support `-exec {} +` which further reduces the number of reasons to invoke `xargs`: find . -type d -exec sh -c ' for x; do do_foo "$x" do_bar "$x" do_baz "$x" done ' _ {} + (example above shows how to make proper use of this feature with an explicit shell invocation)
- LukeShu 14y agoIt's not a problem with GNU or OpenBSD `find`, and I'm pretty sure that's the case for FreeBSD too. What version of find uses system(3) instead of execv(3)?