Solved Shell script runs from shell prompt but not from cron...

The shell script below runs as expect from the root shell prompt but not from the system cron:

Code:
#! /bin/sh
# backup_to_usb.sh
mount /dev/da0p1 /mnt
tar cf /mnt/update.tar ---newer-mtime-than /mnt/primary.tar /usr/home
sleep 60
umount /dev/da0p1

What am I not seeing? Thanks.

[Edit] Seems you need absolute paths for commands in scripts from cron.
 
The shell script below runs as expect from the root shell prompt but not from the system cron:

#! /bin/sh # backup_to_usb.sh mount /dev/da0p1 /mnt tar cf /mnt/update.tar ---newer-mtime-than /mnt/primary.tar /usr/home sleep 60 umount /dev/da0p1

What am I not seeing? Thanks.
What does your cron job look like?

Also, minor improvement to your script. Ahead of the sleep, run `sync` as this forces completion of disk writes.
 
Copied directly from crontab -l

Code:
# backup to external usb disk formatted for FreeBSD at 08:05 and 13:05 weekdays
5    8    *    *    1-5    /usr/home/parkrow/backup_to_usb.sh
5    13    *    *    1-5    /usr/home/parkrow/backup_to_usb.sh
 

SirDice

Administrator
Staff member
Administrator
Moderator
Any errors in /var/log/cron? Does the logging indicate the script is started? And does /usr/home/parkrow/backup_to_usb.sh have the execute bit set?
 
Maybe put your script in /root/bin/ instead of /usr/home/parkrow/.
I just started using cron after reading this. Cron seems to be very picky.

Or run cron as a user and make use of doas.

Code:
amw@t430 ~> doas crontab -l
@daily            /root/bin/unbound-blacklist-fetch.sh

amw@t430 ~> crontab -l
@hourly                    /home/amw/bin/fccfvr.sh
#@hourly                    /home/amw/bin/crbing.sh
@reboot                    /home/amw/bin/bleach.sh
@reboot                    /home/amw/bin/fccfvr.sh
@reboot                    /home/amw/bin/hblock.sh
@daily                    /home/amw/bin/hblock.sh
#@every_minute                /home/amw/bin/redshift.sh
*    21-23    *    *    *    /home/amw/bin/redshift.sh
*    0-6    *    *    *    /home/amw/bin/redshift.sh

amw@t430 ~>
 
Sample output snipped from /var/log/cron. I changed the execute time in crontab, which is why the time field shows 14:02 not 09:05 or 13:05.

Jul 21 14:02:00 pr4 /usr/sbin/cron[1641]: (root) CMD (/usr/home/parkrow/backup_to_usb.sh)

There were no error messages.
 

SirDice

Administrator
Staff member
Administrator
Moderator
The shell script below runs as expect from the root shell prompt but not from the system cron:
Format of a user's crontab and /etc/crontab is slightly different, /etc/crontab requires a user account to run the script on. But I recommend just using root's crontab and leave /etc/crontab untouched.

The entry in /etc/crontab would look like this:
Code:
5    8    *    *    1-5    root /usr/home/parkrow/backup_to_usb.sh
 
Solved. It was a path issue. I added the line:
set PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin
The only command that was in the script that wouldn't run and a similar script which would was mount, so I'm guessing that was the culprit. Thank you all.
[Edit] NOT solved. Script didn't run overnight, so the path thing was a red herring.
 
Sorry, but not solved. Script didn't run overnight. The other script which is similar did run. For completeness this is the other script:
Code:
#! /bin/sh
# /home/parkrow/backup_pr4_parkrow.sh
# called by cron at 18:05 weekdays
# crontab -uroot -e to edit
# crontab -uroot -l to look
# NB file is owned by root

cd /home/parkrow
tar cf /tmp/_home_parkrow.tar *
 

SirDice

Administrator
Staff member
Administrator
Moderator
Check root's mailbox. If the script produces output (error messages for example) those will be mailed to the owner of the crontab (which is root in this case). You could also redirect the output of the commands to a log file; > /var/log/mycrontab.log 2>&1. There's no error checking in your scripts, it's possible for that first mount command to fail (for whatever reason), which in turn would cause the commands after it to fail too.
 
'Check root's mailbox.' Sendmail is disabled. I'll re-enable it. I'd like to try sending errors (would they go to stderr?) to a file but I'm not sure exactly how to do that. This '> /var/log/mycrontab.log 2>&1' doesn't have enough context for me I'm afraid. Thanks for continued help.
 
Hmm, enabling sendmail was a bad idea. After I changed rc.conf entry and rebooted a huge amount of disk activity ensued and I couldn't log in at the console. I managed to log in over ssh and kill the sendmail processes. I've disabled sendmail again so now everything is back to normal. I'd still like to see any error messages however.
 

SirDice

Administrator
Staff member
Administrator
Moderator
This '> /var/log/mycrontab.log 2>&1' doesn't have enough context for me I'm afraid.
I was kind of hoping you understood the concept of 'redirection' in a shell. It's a pretty basic function in a shell script.
 
Err, solved again I hope. I used the absolute path for the mount commands:
/sbin/mount /dev/da0p1 /mnt
That seems to have corrected the problem. We shall see. Thanks everyone for your patience.
 

SirDice

Administrator
Staff member
Administrator
Moderator
/sbin is in the default PATH of a cronjob.

Code:
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

That said, it's always good to use the fully qualified path of a command and not to rely on PATH in scripts.
 
Solved. It was a path issue. I added the line:
set PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin
The only command that was in the script that wouldn't run and a similar script which would was mount, so I'm guessing that was the culprit. Thank you all.
[Edit] NOT solved. Script didn't run overnight, so the path thing was a red herring.
No, it was a path issue, if what you said above was what you added, i.e.

"set PATH=..." This is sh, so "set" is incorrect.

With a proper "PATH=..." statement, mount would have worked as was.

Check /etc/crontab for syntax at least, noting what SirDice said about differences with user crontabs, and other advice including redirection and writing to logs.

Personally, I've always used /etc/crontab for what its first line says it is - root's crontab - but also add /root/bin to PATH and put extra scripts there.

Also, do you not get system mails such as daily, weekly, monthly periodic reports - or anything else that mails root - to /var/mail/root?

You can read that with less(1), if mail(1) is too challenging at first.
 
Thanks all. I've just checked the USB disk this morning and the script seems to be running correctly now. The only change I made was adding the path to mount.
 
Top