views:

375

answers:

2

I've got a script that calls out to a bunch of commands, some of which are noisy to stdout, some to stderr, some to both. I intend the script to be run by cron, so I don't want it to be noisy and mail me every day -- only in error conditions. So I do:

be_quiet() {
  # save stderr in FD 3
  exec 3>&2 

  exec &> /dev/null
}

die() {
  # restore stderr
  exec 2>&3

  echo $* > /dev/stderr
  exit 1
}

Then, i.e.

be_quiet
mkdir -p $CLIENT_ROOT || die "Could not create client root."
cd $CLIENT_ROOT || die "Could not cd to client root."

The intent being that I get specific and meaningful-to-me messages if there is an error, and nothing otherwise. But what I'm seeing now is just

line 48: /dev/stderr: Permission denied

When run from the command line, this works. When run via cron, it gives the permission denied message. I'm unclear why.

+1  A: 

Instead of

exec 2>&3

do

exec 3>&-
Dennis Williamson
A: 

Why not just redirect stdout in the cronjob to /dev/null? Don't use the be_quiet function, and change die to:

die() {
    echo "$*" >&2
}

Then, in your cronjob:

* * * * * /path/to/script.sh >/dev/null

You should only get mail from cron when your script outputs something using the die function.

Marc Bernstein
> Why not just redirect stdout ...Because some of the commands that I run are noisy to stdout, and some to stderr (and some both). As I said in the very first sentence of my question.
arantius
I must have misunderstood, you said you only want to be mailed for error conditions so I assumed you didn't want to see anything at all from stdout and everything from stderr.
Marc Bernstein