A simple backup script using rsync

Today I’m going to present you a simple backup script that I wrote a while ago to maintain backups for my home computers and my server.

This script requires only one program to be installed, rsync. And optionally ssh if you want to store your backups on a remote machine.

With rsync you can do a lot of things, but in this post I’m going to explain only a simple way to copy a folder into another located:

  • on the same computer (for example an external hard drive);
  • on a remote computer (for example a server or a NAS).

Let’s start by examining the contents of the following script:


#       croma25td simple backup script v1.0
#       croma25td at gmail dot com

#user defined variables

#destination folder on the local or remote machine

#server parameter -- use this only if you need to backup on a remote machine (via internet or local network)
#the ssh host with username@address
#the ssh port, 22 by default
#the path for the private key, with this you don't have to provide a password during the connection via ssh, usually stored in ~/.ssh/id_rsa.

#the log file, usually in /var/log

#the header for the new log
echo '-----------------------------------------------------------------------------' >> $LOG_FILE
date >> $LOG_FILE

#rsync command list
#the actual commands -- remote machine version
rsync -aR --stats --delete --rsh='ssh -p '$PORT'  -i '$KEY_PATH'' /etc $HOST:$DEST &>> $LOG_FILE
rsync -aR --stats --delete --rsh='ssh -p '$PORT' -i '$KEY_PATH'' /home  $HOST:$DEST &>> $LOG_FILE

#the actual commands -- local machine version
rsync -aR --stats --delete /etc $DEST &>> $LOG_FILE
rsync -aR --stats --delete /home $DEST &>> $LOG_FILE

The first section of the script will contain the user defined variables:

  • DEST: is the destination folder of your backup; this is the full path on your local or remote machine;
  • HOST: used only if you need to save the data on a remote machine, it’s the combination of the username (with write permissions on DEST folder) on the remote machine plus the hostname; the format is: username@hostname;
  • PORT: the ssh port, by default 22;
  • KEY_PATH: the fullpath to the local user’s (who executes the script) private key;
  • LOG_FILE: the fullpath to a logfile on the local machine (logs are usually stored in /var/log/).

The second section will print only a small header on the log file at each run of the script to separate the old outputs and know the last backup date.

The third and most important section issues the rsync commands, one per folder to backup. In this example we are going to backup two folder, /etc and /home where are stored respectively the system configuration and the user’s datas. Add one line per folder you want to backup.

Each rsync command has some parameters:

  • -a: ‘archive’ activates recursion into the folders and preserve all file’s metadata;
  • -R: ‘relative’ will create the same folder structure on the server;
  • –stats: rsync will write, at the end of the job, a small report;
  • –delete: activate the propagation of file’s deletion: if a file is deleted on the source it will be deleted even in the backup; remove this if you want to preserve all your old datas!

Then there are the connection parameters (if applicable), the source folder and the destination folder:

  • to store the data on a remote machine: rsync -a –stats –delete –rsh=’ssh -p ‘$PORT’ -i ‘$KEY_PATH” /home $HOST:$DEST
    We are using ssh as transfer protocol using the private key for the autentication, then we specify the source folder and the destination folder stored on the server.
  • to store the data on the same local machine: rsync -a –stats –delete /home $DEST
    We are telling rsync to copy the data from /home to $DEST.

At the end of the command there is the &  operator that tells bash to fork the process in a subshell and >> $LOG_FILE  to redirect all outputs to our log file.


Now a three-step how-to to create a private/public set of keys to authenticate via ssh:

  • execute this command with the user that will launch the script (manually or with a cron):

    Then follow the instructions: you have just created your public and private keys; Don’t use any passphrase if you want to execute this script with a cron job otherwise the script will wait for a password that you can’t enter… so just press enter two times to enter a blank passphrase;

  • save into the server your public key so you can authenticate on it by using your private key (do not share this one with anyone!):
    ssh-copy-id -i ~/.ssh/ remote-host

    Change remote-host to your server host;

  • try to login with:
    ssh remote-host

    If it’s all ok it shouldn’t be necessary to write a password.

As always if you have any questions of suggestions just use the comments below 🙂


PHP-Zend 1: create an ImageController

During the development of a website I encountered the following problem: how to load some images located outside the document root into a ZF1 view? Obviously we could move these images into the document root but just to be sure we decided to leave them outside (these images are created with an external script), and in that place it’s impossible to get them with the standard approach (<img src=”relative/path”> ).

Now I found, thanks to a hint from a senior colleague, a way to overcome this problem: create a Zend Framework (we used the version 1.12.3 in this project) controller that has only to load the image and create a response with only the image within. By using a ZF controller you’ll be able to check if the user has the permission to open the image with a few queries and by using the current user session.

Now the only thing to do is to call this controller with a parameter: in the project I used the id of the image because the path is saved into a mysql table, but obviously you can use what you need.

Here comes the self-explanatory snippet of this controller:


class ImageController extends Zend_Controller_Action {
    public function thumbAction(){
        //controller headless, you don't need to create any views in this way

        //fullpath of the folder containing the thumbnails
        $thumb_path = realpath("../path/from/zend/root");

        //with the id as parameter I find the row into the database
        $mapper = new Application_Model_YourImageTable();
        $row = $mapper->find($this->getRequest()->getParam('id'));

        //I check if the user is logged, otherwise I redirect to the homepage
        $auth = Zend_Auth::getInstance();

            //now i can load the image because i know the path and it's name (stored into the db)
            $image = file_get_contents($thumb_path.'/'.$row->getThumb());

            //creating the response...
            $this->getResponse()->setHeader('Content-Type', 'image/png');
            //if the action is not permitted do something, in my case I redirect the user to the homepage
            $this->_helper->redirector('index', 'index');


Now when you want to load this image you only have to write a code like this:

<img src="<?php $this->url(array('controller' => 'image', 'action' => 'thumb', 'id' => $id)); ?>">

New blog (again)

Hi all,

Today I’m going to re-launch my blog, because I feel like that this is the right time to restart blogging about one of the thing that I like most: programming. Remember that you can find my personal website at where you can find my cv, my competences and a biography.

I imported some of the old posts and some pages (in Italian, probably I’ll start translating them soon).

Why all this? Well, right now I’m doing an internship while I study for my second level degree in computer science. As you may know I took my first degree in cs in december 2012 and here in Italy we have a two level system: a first degree after 3 years and a second one after other two years.

So since, right now,  I’m working in a web agency I’ll post here the best solutions to some not-trivial problems that I encountered in my daily life as a programmer.  So expect posts about php (zend, magento, …), java (spring, hibernate, …),  android and so on.

The posts level will be mid-high, since I don’t have the time to do basic tutorials.

Obviously I have not forgotten that during the past three years I created some utilities, such as x264Gui (over 30000 downloads 🙂  ),  so expect some updates and maybe some new projects… not that my free time will allow me to start new projects… but who knows 🙂

At the end I want to apologize for my English, I know that it’s not that perfect but I’m trying to improve it (by practise :))

Daniele Canciani aka croma25td