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


x264Gui 0.9.6 beta1 – update

Now you can use a 8 bit input video with the “high444_8b” AVC setting. This will produce a 10bit video using high444pp. The other AVC setting “high444” will produce the same video but with a 10bit input video.

I also added the support for “high422” and “high444” into the profile system: now when you create a profile with “–high444” or “–high422” the GUI select the 10bit x264 binary; so you can do what you want with the “–output-csp”, “–input-csp”, “–input-depth” and not only the two things provided with the “high444” and “high444_8b” setting.

As always you can download this beta build from: download x264Gui 0.9.6 beta
Take in mind that this only the executable: so replace your local x264Gui.exe with this.


x264Gui 0.9.6 beta1


Just a small update regarding x264Gui. Due to some requests I added the option “high444”. Take in mind that this very first implementation is very simple and so you must know what you are doing.

To use “high444” you *must* use e 4:4:4 10bit input! If you don’t have a input with these characteristics the only way to use “high444” is by passing to x264 an avisynth script (with the needed filters…).

The “high444” implementation is done by adding this command:
“–profile high444 –input-csp i444 –output-csp i444 –input-depth 10”
As you can see you *must* use a 4:4:4 10bit input file.

I also added the “chroma-qp-offset” option, useful when you are using the “high444” profile.

You can download this beta build from: download x264Gui 0.9.6 beta
Take in mind that this only the executable: so replace your local x264Gui.exe with this.