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
.