# Backup samba server using rsync and crontab



## darin (Jun 19, 2011)

Our Samba server is running FreeBSD 8.2, just upgraded from 6.1 that had served us well until a drive started to die. My backup method fails, but I can't find my mistake. Hope someone else can. First I created backup scripts, these typically look like:


```
#!/bin/sh
rsync -a --delete /usr/home/access/ /opft/main/weekly/access/
rsync -a --delete /usr/home/engineers/ /opft/main/weekly/engineers/
rsync -a --delete /usr/home/files/ /opft/main/weekly/files/
rsync -a --delete /usr/home/pacsdata/ /opft/main/weekly/pacsdata/
rsync -a --delete /usr/home/reception/ /opft/main/weekly/reception/
rsync -a --delete /usr/home/accounting/ /opft/main/weekly/accounting/
```

This is the weekly script, there are others. If I run this manually it works fine. The permissions of these files are as follows:


```
-rwxr-xr-x  1 root  wheel  188 Jun 18 12:46 admin.sh
-rwxr-xr-x  1 root  wheel  417 Jun 18 12:45 dailyMWF.sh
-rwxr-xr-x  1 root  wheel  410 Jun 18 12:44 dailyTT.sh
-rwxr-xr-x  1 root  wheel   64 Jun 18 16:56 test.sh
-rwxr-xr-x  1 root  wheel  404 Jun 18 12:43 weekly.sh
```

Next when *su*'d to root, I edited crontab by using `crontab -e`
root's crontab looks like this:


```
#Minute hour    mday    month   wday    who     command
#
1  22  *  *  1-5   /bin/sh /usr/local/etc/backup/admin.sh
15 0   *  *  0     /bin/sh /usr/local/etc/backup/weekly.sh
15 22  *  *  1,3,5 /bin/sh /usr/local/etc/backup/dailyMWF.sh
15 22  *  *  2,4   /bin/sh /usr/local/etc/backup/dailyTT.sh
54 16  *  *  1,6   /usr/local/etc/backup/test.sh
30 14  *  *  0     /bin/sh /usr/local/etc/backup/test.sh
```

The two tests at the end is just me playing around and watching logs, hence the odd times. After the allotted time, for example the test at 14:30, this is what the cron log shows:


```
Jun 19 14:30:00 crash /usr/sbin/cron[78543]: (root) CMD (/bin/sh /usr/local/etc/backup/test.sh)
```

Everything looks fine, but no files get copied to the 1.5Tb (/opft) backup drive. As you can see I have tested crontab with /bin/sh preceding the script and without. Same result both ways, cron log looks fine, nothing gets copied. Does anyone know why?

One final point, I didn't know if rsync expects the directory structure at the destination so I have created the main directories.

Thanks to all that take the time to read this


----------



## DutchDaemon (Jun 19, 2011)

This has been answered quite a lot of times on the forums already: cron has a limited PATH, which typically does not include /usr/local/bin, which is where rsync lives. Either use full path names for all commands in scripts executed from cron, or extend the PATH in the crontab, e.g.


```
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin
```


----------



## darin (Jun 19, 2011)

Off to edit and test again. I did see a post relating to the limited path for cron, but for some reason didn't relate that to rsync path. Thanks for the quick response.


----------



## gpw928 (Jun 19, 2011)

Hi Darin,

The corollary is that you also always need to check for errors...  There would have been a "not found" message emitted by the shell on the standard error.

In the absence of any other defence, you would have found that error message in the cron output which, by default, is mailed to the crontab user (root in your case).

As a programmer, I always direct any error message to STDERR.  I then also catch and log all cron job output, and mail it to somebody who cares.  My standard cron job wrapper looks something like this:


```
#!/bin/sh
PATH=/bin:/usr/bin:/usr/local/bin
export PATH
# Set LOG and MAILTO sensibly
LOG=somefile
MAILTO=somebody
# Log standard out
exec 1>$LOG
# Log standard error (to the same file in this case)
exec 2>&1
# Run your batch job
...
# Mail any news to somebody who cares
[ -s "$LOG" -a -n "$MAILTO" ] && mailx -s "Batch job errors" $MAILTO <$LOG
```

Quite apart from the above, I generally try to write my batch jobs so that they:


record successful actions to a separate log file (not shown above);
say nothing on STDOUT; and
give meaningful diagnostics on STDERR if there was a problem.
In this way, there is nothing to do if everything worked.

However I generally leave all the logs around for forensic examination, and tidy them up with a separate log rotation.

You would still have to read root's mail occasionally, as there are small windows where your cron job can fail without reporting errors in any log.

Cheers,

-- 
Phil


----------

