0

I'm experiencing a small problem with a cronjob that runs a script of mine.

The script looks something like this, it is named create_report.sh:

#!/bin/bash
cd /work/directory
/some/command.sh > reports/report_$(date -d "1 day ago" +%Y%m%d).txt

This is obviously a little simplified, but after writing the output to some file that file gets attached to an email and sent to me.

When I run this "manually" it works fine and the report file has contents.

Then I created a cronjob using crontab-generator.org which runs that script each morning at 7 am and mutes the output of the script.

0 7 * * * /path/to/script/create_report.sh >/dev/null 2>&1

When the cronjob runs the script, the report files get created and sent to me, but they're empty. I could probably figure out a way around this behaviour myself, but I didn't expect this to happen, can someone explain to me how this happened and maybe point out the correct way to make something like this happen?

To clarify: I'm not interested in the output of create_report.sh but the report-File it creates.

Thanks in advance!

  • do actual script include bash shebang ? (e.g. #!/bin/bash in first line ) – Archemar Mar 29 '17 at 6:50
  • Yes, it does, that was a part that I probably shouldn't have ommited, I'm going to add it. It is marked as executable as well. – Maurice Mar 29 '17 at 6:52
  • fine, have you consider getting the actual output of create_report when run by cron ? I mean redirecting to /some/file.log instead of /dev/null might give you a clue. – Archemar Mar 29 '17 at 7:06
  • If /some/command.sh relies on any variables that are set by your login shell, those won't be set by cron. see also: unix.stackexchange.com/q/67940/117549 – Jeff Schaller Mar 29 '17 at 10:57
  • @JeffSchaller that was the problem, I didn't realize cron wasn't reading the .bashrc, .profile or .bash_profile files. Would you mind posting this as an answer so I can accept it? – Maurice Mar 29 '17 at 12:20
1

When cron executes your cron job, it will (eventually) execute bash to run your script, but that bash instance will be non-interactive and not a login shell, so it will not source any of your profile files.1 If your /some/command.sh relies on any of those profiles (to set a variable or perform activity), then you need to:

  • explicitly source those files, or
  • set BASH_ENV (to the right file) before executing the script, or
  • set the -i option in the she-bang line (to load ~/.bashrc), or
  • set the -i and --login options in the she-bang line (to load the first of ~/.bash_profile, ~/.bash_login, or ~/.profile), or
  • set those variables or perform those activities within /some/command.sh

Reference:

Footnote:

  1. unless you've already set BASH_ENV
1

I see 2 issues:

1. /some/command.sh > reports/report_$(...).txt Provide an absolute path to for reports directory like: /some/command.sh > /home/user/reports/report_$(...).txt

Since it does work on manual execution, I assume the script runs in a different CWD when executed by the cron daemon.

2. Do you run this cronjob under the same user?

If not, check if the actual user, who's running this cronjob, has all required permissions (such as writing to the reports dir).

If nothing works, you may debug further by watching the syslog (e.g. tail -f /var/log/syslog | grep CRON) and write any output (stdout AND stderr) to disk: 5 * * * * /path/to/script/create_report.sh >>/tmp/cronlog 2>&1

  • Thanks for your answer. While you are pointing out valid concers I kept both of them in mind and the actual script gets called as the correct user and executes the command in the correct directories. The problem was that Environment Variables from the .profile - File weren't used by cron, which was pointed out by @Jeff Schalker in the comments to the question. – Maurice Mar 29 '17 at 12:35

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.