1

I've looked through a bunch of cronjob troubleshooting guides, but I can't seem to find what I'm doing wrong. This script runs just fine if I run it manually. Running it from crontab just isn't working. Here's what the script looks like:

#!/bin/bash

#d1 establishes the date range as 10 minutes prior to running the script to the time the script is run.
d1=$(date --date="-10 min" "+%b %_d %H:%M")

#d2 formats the date for the script.
d2=$(date "+%b %_d %H:%M")

#d3 displays the standard current date format.
d3=$(date)

#sent_emails variable shows the number of emails sent in the last 10 minutes. It accomplishes this by searching for the keyword "sent" in mail.log, then filtering that list down to any sen$
sent_emails=$(find /var/log/mail.log | xargs grep "sent" |  awk -v d1="$d1" -v d2="$d2" '$0 > d1 && $0 < d2 || $0 ~ d2' | wc -l)

#If 50 emails are sent in the last 10 minutes, then postfix is stopped and the date + the number of emails sent in the last 10 minutes are printed. If less than 50 are sent in the last 10 $
if [ $sent_emails -lt 1 ]; then
    echo "$d3 - $sent_emails emails sent in last 10 minutes"
else
    postfix stop
    echo "$d3 - $sent_emails in the last 10 minutes; postfix terminated"
fi

The script is set to be executable (chmod u+x) and is owned by root:root. It works every time I run it manually. I have the conditional set to "1" right now for testing. I won't want 1 email to trigger a postfix shutdown in the future.

Here's what my crontab looks like:

*/1 * * * * /bin/bash /home/rommy/spam_monitor.sh &> /home/rommy/cronresults.txt

There is an extra line after the above command in the crontab. Nothing ever appears in cronresults.txt. I have it running every minute right now for testing. It won't run so often in production.

Any help would be greatly appreciated!!

2

You are using &> for redirecting both STDOUT and STDERR, which is a bashism. As the default shell for cron (not the same thing as your scripts shebang) is sh (which is dash in Ubuntu), it does not understand &> syntax. As a result it is treating the & to put the shell script as a background job.

To overcome this, use the portable way of redirection :

*/1 * * * * /home/rommy/spam_monitor.sh >/home/rommy/cronresults.txt 2>&1
2
  • This let me troubleshoot the output of the script! Thank you! What does the 2>&1 do for the script? Aug 21 '15 at 15:06
  • @JosephOdell 2>&1 will send the STDERR to where STDOUT is going already, in your case STDOUT was being redirected to a file so STDERR will also follow..
    – heemayl
    Aug 21 '15 at 17:53
0

This is more of a style criticism. A Best Practice is to quote strings that the shell should NOT expand with '', and strings that the shell should expand with "". Thus rather than:

d1=$(date --date="-10 min" "+%b %_d %H:%M")

Use

d1="$(date --date='-10 min' '+%b %_d %H:%M')"

Also, your

find /var/log/mail.log | xargs grep "sent" |

is more easily done by

grep 'sent' /var/log/mail.log |

You could also add, after this line:

d3="$(date)"

echo "At $(date) d1=/$d1/,d2=/$d2/, d3=/$d3/" >>/tmp/spammonitor.log

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.