I'm using find
with the -exec
option in console, on FreeBSD (for example, find . -exec sha1 {} \;
).
-
How do I correctly place (and if needed, escape) redirect and other execution control symbols that could syntactically apply to either of the exec command or the find command, such as > >> | and &, where I might want the symbol to apply to the
find
or theexec
commands on different occasions? -
On the same theme, what is the syntax if I want to use
tee
to view the output of the -exec commands on the console (to watch progress) and also appended to a file (for later use)?
(I know shells vary but hopefully the most used shells such as sh/csh are quite similar?)
Update:
In part, I want to learn if nested find -exec
can be done without scripting, as a simple command. Here is the use-case that prompted the questio :
- outer
find
: find all subdirs matching DIR_MATCH_TEXT inDIR1
- inner
find
: for each matching subdir found in the outer loop (call it DIR2), execute the commandfind DIR2 -name "FILE_MATCH_TEXT" -exec sha1 {} \; >> DIR1/DIR2_hashes.txt
The aim being to create a set of files, one for each matching subdir, containing the output of some find -exec
action on that subdir.
By this I mean that, if /backups
contains /jan2017
and /feb2017
, the result will be two files at /backups/jan2017_hashes.txt
and /backups/feb2017_hashes.txt
, with jan2017_hashes.txt
containing the output from sha1
for (say) all .pdf files in /backups/jan2017
, and feb2017_hashes.txt
containing the output from sha1
for all .pdf files in /backups/feb2017
.
From replies so far I gather the outer find
would have to use a shell call as the argument to -exec
?
Best Answer
I/O redirection and piping are functions of shells (e.g., bash). Looking at the source code of the
find
command (https://www.gnu.org/software/findutils/), the-exec
option forks and directly execs the given command, it does not send it though any shell. Given that, without help, you cannot include piping and redirection in the argument tofind
.You can, however, have
find
invoke a shell and have that shell in turn invoke your command. When running the same through a shell, you have access to the I/O redirection operations exposed by the shell. Consider, for example:That will run
ls -l
on each file found byfind
(the shell refers to that file in this context as$0
) and redirect the output to/tmp/result
. Note that I used>>
instead of>
. Here, find is invoking a shell for each file, so>
will result in each result overwriting the previous -- you'll end up with a file that contains only the output from the last command.Pipes will work as well, with the same caveat of "one exec per file".
All that said, it's not immediately clear to me why you'd want to apply redirection within the context of the
-exec
, or what it would buy you over performing the redirection on the output of find itself.