Use for loop in find exec

To use multiple statements, such as a for-loop, as the argument to -exec, one needs to invoke a shell, such as bash, explicitly:

find .. -name bin -exec bash -c 'for file in "$1"/* ; do echo "$file" ; done' none {}  \;

This is safe even for filenames that contain spaces or other hostile characters.

How bash -c works

One can invoke bash with a command of the form:

bash -c some_complex_commands arg0 arg1 arg2 ...

In this case, bash will execute whatever is in the string some_complex_commands. Those commands can make use of the usual shell positional parameters. The first argument after command, arg0 above, is assigned to $0, the second to $1, the third to $2, etc.

When one executes a normal shell script, $0 is the name of the script and $1 is the first argument that appears on the command line. In keeping with that tradition, the bash -c command was written to assign the file name, {} in find's notation, to $1. Since this script does not have a sensible name, none is assigned as a placeholder to $0.

Tags:

Bash

Find