Destinations‎ > ‎


The shell destination type enables the use of external storage not natively supported by HashBackup, where sending, getting, and removing files can be done via a Unix command or shell script.  Shell destinations can be written in any language.

As an example, (attached below) is a shell implementation of the built-in dir destination.

Shell destinations report success or failure with their exit code.  If a non-zero exit code is returned (failure), the command is retried with exponential backoff like all other destinations.

To make parsing easier, you may want to add a --command option to the end of the run keyword value.  The command line is processed by the regular Unix shell, so things like $VAR, shell functions, and quoting work fine.

IMPORTANT: to avoid errors on your first backup, use:

               hb dest -c backupdir setid <destname>

           on your shell destination before the first backup.

HB adds a command and arguments to the end of the run command line.  Below are the commands HB sends and the shell destination's responsibilities.


exit 0 if the destination is available.  This is used once per worker during startup.

send pathname filename

send the local file pathname to the remote destination and store it as filename.  The file may already exist on the remote, and HB expects send to overwrite the existing file.  This happens for example with DESTID and dest.db.  The file size may stay the same (always with DESTID), so don't use file size as an indication of whether to copy a file; the file should be unconditionally copied.

Some protocols like rsync automatically prevent partial files on the remote by copying first into a temp file then renaming the temp file to the real filename.  If your remote protocol doesn't do this automatically (ftp doesn't for example), it's a good idea to send the file as filename.tmp, then rename filename.tmp to filename, overwriting filename if it already exists.  If the remote cannot rename over an existing file, you can send as filename.tmp, delete filename, then rename filename.tmp to filename.  This runs the slight risk of a failure after the delete, which would have to be corrected manually by renaming filename.tmp to filename on the remote, or will be corrected automatically on the next backup by resending the file.

get pathname filename

fetch the remote file filename and store it in the local file pathnamePathname will not exist on the first get attempt, but may exists on a retry.  This can be used to do a restart, or pathname can be deleted or completely overwritten to start over.

rm filename

remove the remote file filename.  If it doesn't exist, no error should occur.  If the send command creates filename.tmp then renames it, both filename and filename.tmp should be removed on the remote.


NOTE: the run command below is a single line

destname mydest

type shell

run python /home/jim/ --host --port 81 --cred /home/jim/iface.cred --destname mydest

Jim Wilcoxson,
Aug 23, 2017, 4:52 AM