2

The following writes stdout to a logfile and prints stderr:

bash script.sh >> out.log

This again writes both stdout and stderr to a logfile:

bash script.sh >> out.log 2>&1

How to combine both features, so that stdout and stderr are logged to a file and stderr is emailed to my inbox?

Steven Rands
  • 5,160
  • 3
  • 27
  • 56
Fabricator
  • 12,722
  • 2
  • 27
  • 40

4 Answers4

3
bash script.sh 2>&1 >> out.log | tee -a out.log

First, I'm redirecting stdout to file and stderr to stdout (stdout line gets to the out.log file and stderr to pipe).

The tee command prints stdin to both stdout and file (resemblance with the letter T). Thus second, I'm printing the original stderr to both stdout and the out.log file (the -a argument means append).

pacholik
  • 8,607
  • 9
  • 43
  • 55
  • 1
    The only problem with this is that it seems like lines may get reordered, since you now have two processes outputting to the same file. I see no way around this though. I think this is the best answer. – Dan Bliss Jun 02 '14 at 20:43
  • @pacholik, thanks! It's interesting (and counter-intuitive) that `2>&1 >> out` get stderr to | while `>> out 2>&1` gets it to out – Fabricator Jun 02 '14 at 22:00
0

You can keep stdout in a separate file and stderr in separate file:

0 * * * * bash script.sh > out.log 2> err.log

and then email yourself err.log file.

anubhava
  • 761,203
  • 64
  • 569
  • 643
0

Here is a working solution:

./myscript.sh &> all.txt 2> stderr.txt
  • &> all.txt to have both stderr and stdout
  • 2> stderr.txt to have only stderr

And then just do whatever you want with those files, such as email logging for instance!

julienc
  • 19,087
  • 17
  • 82
  • 82
0

Using process substitution you can try:

0 * * * * bash script.sh >> out.log 2> >(exec tee >(exec cat >> mail))

Or

0 * * * * bash -c 'exec bash script.sh >> out.log 2> >(exec tee >(exec cat >> mail))'

exec cat >> mail imitates mailing. Replace it with a command that actually does the mailing.

konsolebox
  • 72,135
  • 12
  • 99
  • 105