4

Any "find -exec" guru's around.

I have a folder of files I need to send to sendmail (they appear in there when something bad has happened).

  • The command

    find . -type f -exec sendmail -t < {} \;
    

    gives me

    -bash: {}: No such file or directory
    

    It doesn't seem to like the <.

  • And this

    find . type -f -exec cat {} |sendmail -t \;
    

    gives me

    find: missing argument to `-exec'
    

    It doesn't seem to like the |.

What is wrong?

Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
Richard
  • 43
  • 1
  • 3

2 Answers2

5

It looks like you'd like this redirection (<) or pipe (|) to belong to the inside of the -exec … ; statement. This doesn't work because they are handled by your shell before find even runs.

To make them work you need another shell inside -exec … ;. This other shell will handle < or |. Respectively:

find . -type f -exec sh -c 'sendmail -t < "$1"' sh {} \;
find . -type f -exec sh -c 'cat "$1" | sendmail -t' sh {} \;

Note: find . -type f -exec sh -c 'sendmail -t < "{}"' \; is less complicated but wrong. This is explained here: Is it possible to use find -exec sh -c safely?

Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
  • When I was using a command similar to this: `$ find -name "foo[1-5].tst" -exec echo "filenameis {}" >> {} \;` It kept generating a file named '{}' with the echoed text. After searching for few hours I found your answer, thanks for explaining in plain words :). Just to be sure, is the following assumption valid? The shell interprets the above command as follows part 1:`find -name foo[1-5].tst -exec echo 'filename is:{}'` part 2: `(output of part 1) >> {}` #redirect the output of part 1 to the file named '{}' – Doe McBond Jun 17 '19 at 19:13
  • 1
    @DoeMcBond I think the assumption is almost valid; you forgot `\;` in your explanation, the rest seems basically OK. [Redirection doesn't have to be at the very end](https://superuser.com/q/1335333/432690). – Kamil Maciorowski Jun 17 '19 at 19:22
-1

In both cases your redirection is parsed by the shell, not by find, so you need to escape it:

find . -type f -exec sendmail -f \< {} \;

works as expected.

Eugen Rieck
  • 19,950
  • 5
  • 51
  • 46