← Back to context

Comment by ndsipa_pomu

1 month ago

It's to deal with problematic filenames (e.g. containing a newline) and enables setting of variables within the current process. Putting multiple commands into the "-exec" of find is possible, but looks horrible. To be fair, my example didn't use multiple commands, so your version is okay for simple processing.

Don't get me wrong, the BASH man page is great, it's just that I prefer to work with examples.

For reference, here's the Greg's Wiki explanation: https://mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_....

On my computer

    touch "$(echo -en 'a\nb')"
    find . -type f -name '*.mp3' -exec bash -c "echo '{}'; ls '{}'" ';'

works just fine, but maybe it doesn't work everywhere.

If you don't like how the multiple commands look like, you can always write it like this:

    find . -type f -name '*.mp3' -exec bash -c "
        echo '{}'
        ls '{}'
    " ';'

  • Yep, you can chain multiple commands with find's "-exec", but I'm not a fan of it myself. I suspect setting variables in the current process is trickier though.

    (Very minor nitpick, it should be 'a\nb.mp3' to be included, but that does work fine)

    Incidentally, ShellCheck isn't happy with that although I don't follow their reasoning:

      find . -type f -name '*.mp3' -exec bash -c "
                                               ^-- SC2156 (warning): Injecting filenames is fragile and insecure. Use parameters.
    

    https://www.shellcheck.net/wiki/SC2156