Looking for comfortable way to synchronize a local folder with a web-server folder via terminal or shell script I got cought by rsync. But the way to get rsync running under Mac OSX was not so easy as the result look.
Rsync is very fast because it only considers files that were modified like changed sizes oder modify date. And if rsync uses a remote access with SSH it uses a special algorithm to transfer only the changed data of one file and not the whole file. So a lot of traffic is saved.
But in normal life it's not so easy to combine rsync with ssh access in a shell script. You have to deal with some hurdles on an Mac OS to get it work. SSH as standalone won't work in a shell script. You have to use sshpass. But it is not trivial to install sshpass on Mac for beginners or not terminal used operators.
At first you have to install sshpass. But
sudo apt-get install sshpass
won't work, because apt-get isn't supported by Mac OS. So you will find the recommendation to use instead Homebrew as package manager. But let me tell you: It won't work in our case either. If you try to install sshpass with
brew install sshpass
you will get the message
Error: No available formula for sshpass We won't add sshpass because it makes it too easy for novice SSH users to ruin SSH's security.
The security matter is something you have to think about. Because you will using your ssh password in plain text in the script. Sure there are other possibilities you can google. If you need Homebrew after all, it can be installed with:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
To install sshpass directly we download the package to our Download folder and compile and install it.
cd Downloads curl -O -L http://downloads.sourceforge.net/project/sshpass/sshpass/1.05/sshpass-1.05.tar.gz tar xvzf sshpass-1.05.tar.gz cd sshpass-1.05 ./configure make sudo make install
Now we can tinker the commands for synchronizing. The next code is for example used as an alternative to FTP. From a local folder the files are uploaded to an remote web server.
#!/bin/sh USERPATHemail@example.com:www/mywebsite/ PASSW=your_password LOCALPATH=_yourfolder/ sshpass -p $PASSW rsync --progress --size-only --exclude '.svn' -avz $LOCALPATH -e ssh $USERPATH
Here we use --progress to show the progress of synchronizing. --exclude 'file_pattern' can be used to exclude files or folders from transfer. The parameter --size-only takes care that only new files and files that have a different (changed) file-size are synchronized. That is very interesting if you use Jekyll for building your website. Jekyll regenerates all files of your website. So all files get a new modify date and are then different compared to the files laying on web server and the whole bunch would be synchronized.
If you want to go the opposite way, means you want to backup a web server folder to a local folder, you have to swap Source and Target
#!/bin/sh USERPATHfirstname.lastname@example.org:www/mywebsite/ PASSW=your_password LOCALPATH=_yourfolder/ sshpass -p $PASSW rsync --progress -avz -e ssh $USERPATH $LOCALPATH
Like I said the result looks simple. But that five rows can you take hours if you're not familiar with linux console or mac terminal.