Problem running bash script in cron
I created a script in bash to be run in cron. When the script was executed manually, it would run just fine. But when I used cron to run it, it would not run. The script was for backup of certain files, and its major steps were:
- Tar the folder
- Put the folder on a Windows server using Samba
I found a post by ichbindev online (cron runs but script is not executed properly) about a similar problem but no solution. Searching Google revealed many, many users with the same problem. Since my aim was very similar to what ichbindev wanted to do, I took the liberty of emulating his code but changing it for my own requirements. His original code was:
#!/usr/bin/env bash
Date=`date "+%Y%m%d%H%M%S%n"`
DBUser="mydbuser"
UserPassword="mydbpassword"
BkpUser="mybkpuser"
BkpPassword="mybkppassword"
mysqldump mydatabase -u$DBUser -p$UserPassword > /home/me/daily-backup/mydatabase.sql
cd /home/me/daily-backup/
zip mydatabase-"$Date".zip mydatabase.sql
smbclient "//bkpserver/backup" -I10.10.1.10 -Wworkgroup -U $BkpUser%$BkpPassword < /home/me/scripts/smbclient-commands
rm mydatabase.sql mydatabase-"$Date".zip
cd /home/me/tempfiles/
rm -f *.csv
And I changed it (vim /home/me/scripts/dailybackup.sh) to look something like:
#!/bin/bash
Date=`date "+%Y%m%d%H%M%S%n"`
BkpUser="mybkpuser"
BkpPassword="mybkppassword"
tar cvzf /home/me/mybackups/dirone-"$Date".tar.gz /home/me/dirone/
tar cvzf /home/me/mybackups/dirtwo-"$Date".tar.gz /home/me/dirtwo/
cd /home/me/mybackups/
/usr/bin/smbclient "//bkpserver/backup" -I10.10.1.10 -Wworkgroup -U $BkpUser%$BkpPassword -c "prompt; mput *.tar.gz; quit;"
rm /home/me/mybackups/*.tar.gz
I made the file executable by user (chmod u+x /home/me/scripts/dailybackup.sh). I found that if I didn’t use cd /home/me/mybackups/ and instead used the complete path within the smbclient command (mput /home/me/mybackups/*.tar.gz), it wouldn’t transfer any files even when running the script manually. I also noticed that when using cron, the script would not put more than four files using smbclient (manually, it would put all files). Don’t ask me why.
Now my crontab file looked like his as well:
00 05 * * * /home/me/scripts/dailybackup.sh
But I had the same problem as him: cron would not run the script. It would create the tar file but not move it to the backup server. After doing lots of research, it turned out that cron has the default shell of sh. It can be determined by doing
less /etc/crontab
For some reason sh did not run smbclient while bash did. So I tried to change sh to bash in /etc/crontab and then restarting the cron service (sudo /etc/init.d/cron restart in Ubuntu) but it did not solve the problem. Lots more googling brought up a very useful page: HowTo: Using the cron shell tool to automate procedures – Part 2 of 3. It had one minor change to the crontab file, and now my crontab (crontab -e -u 'me') looked like:
SHELL=/bin/bash
00 05 * * * /home/me/scripts/dailybackup.sh
Notice that we set the SHELL variable within the crontab file so that instead of sh cron uses bash to run all scripts. This one change made all the difference and everything worked fine.
I think I should also look into the possibility of mounting the shared directory and then directly using it. I will post back when and if I try it and discover how it might work.
Thanks for the post! =)
Same problem … did everything except that last step of setting the SHELL in the crontab … will know tonight if it fixes my problem.