Scenario: We have a legacy system running FreeBSD 4.7 (please, no laughing. It's being retired at the end of the year.. I just need to keep it alive and backed up until then) and I have some database dump scripts that I run daily with a cron job. I begin the script with #!/usr/local/bin/bash. The script uses the date command to put the date as part of the file name of the dump file. When I run the script manually it works as expected. However, when I put it into a cron job, it fails. I checked my error log and it's failing at the part of the script where I use backticks and the date command for the file name (I also tried $(date...) in the file name and that gave the same error. So I then tried adding /usr/local/bin/bash /path/to/script.sh in the cronjob and it still had the same error.

So my guess is that it's not switching to a bash shell when it runs. I first thought about adding echo $SHELL to my script to see, but I found that switching shells doesn't actually switch the value of the SHELL variable.

Has anyone had a similar issue with FreeBSD? Or does anyone know an alternate way I can check which shell it's using at execution? (I also tried ps >> test.txt and that didn't work in the cron either).

  • 1
    What's the exact error message? Is your date executable located in a path that's covered by crons $PATH setting? – bmk Jun 14 '11 at 17:24
  • The error is "Illegal variable name" – Safado Jun 14 '11 at 19:16
  • if I echoed $PATH in a cronjob, would that show MY path or cron's PATH? – Safado Jun 14 '11 at 19:28
  • cron's PATH. – glenn jackman Jun 14 '11 at 19:32

A few things occur to me while reading this.

If you are running bash echoing the value of $BASH should expand to the full path and filename of the bash executable in use.

How are you calling date in your script. Are you calling it with the full path name or as "date". The later case can result in the use of function, aliases, or whatever happens to be first in the path rather than the date program you expect.

Bash will behave differently in some cases depending on the environment. You may want to dump the environment to a file from the script and look at it running from the command-line and from cron. You may find that the PATH is different or that some other environment variable is set differently. You should be able to dump this to a file in /tmp by putting a line like "env > /tmp/environment.$$" in the script. Each time the script is run it will print out the environment to a file named environment.(pid of script)

You can set also the shell for the entire crontab to whichever shell you want by using "SHELL=/path/to/new/shell" on a line by itself.

  • The file name I use is "data-db-$(date '+%Y-%m-%d').sql". I have also tried "data-db-date '+%Y-%m-%d'.sql". Both work when I manually execute it, but doing it in the cron fails. I've used absolute paths everywhere I can except for the date command (didn't even think of that one). The error I'm getting is "illegal variable name". It actually creates the file with the date in the name, but it's 0 bytes. I'll try dumping all the variables as you suggested and see if something looks out of place. – Safado Jun 14 '11 at 19:23
  • sorry, I used back ticks in the above example. Didn't know back ticks did that on here – Safado Jun 14 '11 at 19:29
  • OK, so the env command shows that the PATH is /usr/bin:/bin, so it is different. However, I've listed the absolute paths on everything (except date, which is at /bin/date). It reported that the shell is /bin/sh. Do you think configuring cron to use /bash instead would fix it? Where would I do this? – Safado Jun 14 '11 at 19:42
  • The fix ended up being declaring the shell variable via SHELL=/usr/local/bin/bash in the users crontab. Everything's working like a beauty now! Thanks a lot for the suggestions. – Safado Jun 14 '11 at 20:32

Try explicitly setting environment variables (e.g. PATH) or explicitly sourcing startup files (e.g., /etc/profile or /home/root/.profile or whatever).

If your cron is assuming another shell, you might want to exec the bash script.

  • Well, the developer who created the service running on this server set the default shell to be the TCSH shell specifically because it could do something that he needed to integrate with his program. Whatever that something was, he warned that switching the shell would break it. – Safado Jun 14 '11 at 19:26

At least some versions of cron interpret '%' as a special character. I can't tell from your answer above if you use that date command in the crontab itself. Consult your man page. It's

man 5 crontab

The other crontab man page is for the crontab command and not the format of the file.

on linux but I'm not sure on bsd.

If that's the case, you can fix it by escaping the % with a \ in front of it.

  • % are interpreted as a newline character and the data the follows is piped to the command's stdin. – Chris S Jun 21 '11 at 3:43

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.