2013-04-28 16:00:22 +02:00
|
|
|
#!/bin/bash
|
2013-04-27 21:00:51 +02:00
|
|
|
|
|
|
|
# ************************************* #
|
|
|
|
# #
|
|
|
|
# sshbackup #
|
|
|
|
# #
|
|
|
|
# ************************************* #
|
|
|
|
|
|
|
|
# **** config section ****
|
2013-04-28 16:02:39 +02:00
|
|
|
version="0.3.1"
|
2013-04-27 21:00:51 +02:00
|
|
|
author="david@socialnerds.org"
|
|
|
|
|
|
|
|
configfile="$HOME/.sshbackup"
|
|
|
|
#rsync options.
|
|
|
|
rsyncoptions="-pogEthrzl --numeric-ids --no-motd"
|
|
|
|
#dotglob option removes bug while rsyncing folder with no visible files in it.
|
|
|
|
remotecmd="shopt -s dotglob; /usr/bin/sudo /usr/bin/rsync"
|
|
|
|
localcmd="/usr/bin/rsync"
|
|
|
|
|
|
|
|
sshkeyfile="$HOME/.ssh/id_rsa"
|
|
|
|
|
|
|
|
versions=999
|
|
|
|
config=0
|
|
|
|
sshkey=0
|
|
|
|
list=0
|
|
|
|
options=$*
|
|
|
|
|
|
|
|
|
|
|
|
# **** function definitions ****
|
|
|
|
bashtrap()
|
|
|
|
{
|
|
|
|
|
|
|
|
echo
|
|
|
|
echo "CTRL+C detected."
|
|
|
|
echo "commiting suicide."
|
|
|
|
exit 1
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
usage()
|
|
|
|
{
|
|
|
|
|
|
|
|
echo
|
|
|
|
echo "usage: sshbackup <options> source destination [versions]"
|
|
|
|
echo "source/destination example: [[user@]server:]/path/to/files"
|
|
|
|
echo
|
|
|
|
echo "OPTIONS:"
|
|
|
|
echo " -h, --help show this message"
|
|
|
|
echo " -v, --version version information"
|
|
|
|
echo
|
|
|
|
echo " -c, --config <file> alternate config file [~/.sshbackup]"
|
|
|
|
echo " -l, --list <file> list of sources and destinations"
|
|
|
|
echo " -s, --sshkey <file> alternate sshkey [~/.ssh/id_rsa]"
|
|
|
|
echo
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
version()
|
|
|
|
{
|
|
|
|
|
|
|
|
echo
|
|
|
|
echo -e "vesion: \033[1;37m$version\033[0m"
|
|
|
|
echo "author: $author"
|
|
|
|
echo
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
preflight()
|
|
|
|
{
|
|
|
|
|
|
|
|
#amiroot?
|
|
|
|
if [ $(whoami) != "root" ]; then
|
|
|
|
echo "aborting mission. you must be root."
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
#source and destination path?
|
|
|
|
if [ -z $sourcepath ]; then
|
|
|
|
echo "aborting mission. no source path given."
|
|
|
|
return 1
|
|
|
|
elif [ -z $destinationpath ]; then
|
|
|
|
echo "aborting mission. no destination path given."
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
#if remote source or destination check for sshkey
|
|
|
|
if [[ $sourcepath =~ .*@.* ]] || [[ $destinationpath =~ .*@.* ]]; then
|
|
|
|
if [ -r $sshkeyfile ]; then
|
|
|
|
#echo "sshkeyfile found. continuing."
|
|
|
|
:
|
|
|
|
else
|
|
|
|
echo "aborting mission. no sshkey found."
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
sshbackup()
|
|
|
|
{
|
|
|
|
|
|
|
|
#creating local rsync options var
|
|
|
|
local cmdopt="$rsyncoptions"
|
|
|
|
|
|
|
|
#move existing versions
|
|
|
|
local num=$versions
|
|
|
|
while [ -d "$destinationpath/0" ]; do
|
|
|
|
if [ -d "$destinationpath/$num" ]; then
|
|
|
|
mv $destinationpath/$num $destinationpath/$((num+1))
|
|
|
|
fi
|
|
|
|
let num--
|
|
|
|
done
|
|
|
|
|
|
|
|
#create destinationpath if not existing
|
|
|
|
mkdir -p $destinationpath/0
|
|
|
|
|
|
|
|
#add link-destination option if existing
|
|
|
|
if [ -d $destinationpath/1 ]; then
|
|
|
|
cmdopt="$cmdopt --link-dest=$destinationpath/1"
|
|
|
|
fi
|
|
|
|
|
|
|
|
#run rsync
|
|
|
|
$localcmd $cmdopt -e "ssh -q -i $sshkeyfile" --rsync-path="$remotecmd" $sourcepath $destinationpath/0
|
|
|
|
if [ $? -ne "0" ]; then
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
#removing obsolet version(s)
|
|
|
|
local i=1
|
|
|
|
while [ -d $destinationpath/$((versions+i)) ]; do
|
|
|
|
rm -rf $destinationpath/$((versions+i))
|
|
|
|
let i++
|
|
|
|
done
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# **** start of script ****
|
|
|
|
|
|
|
|
#initialize bashtrap
|
|
|
|
trap bashtrap INT
|
|
|
|
|
|
|
|
# **** option handler ****
|
|
|
|
if [ -z $1 ]; then
|
|
|
|
usage
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
for option in $options; do
|
|
|
|
case "$option" in
|
|
|
|
-h|--help)
|
|
|
|
usage
|
|
|
|
exit 0
|
|
|
|
;;
|
|
|
|
-v|--version)
|
|
|
|
version
|
|
|
|
exit 0
|
|
|
|
;;
|
|
|
|
-c|--config)
|
|
|
|
config=1
|
|
|
|
;;
|
|
|
|
-l|--list)
|
|
|
|
list=1
|
|
|
|
;;
|
|
|
|
-s|--sshkey)
|
|
|
|
sshkey=1
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
if [ $config -eq 1 ]; then
|
|
|
|
if [ -r "$option" ]; then
|
|
|
|
configfile=$option
|
|
|
|
config=0
|
|
|
|
else
|
|
|
|
echo "aborting mission. cannot read configfile. [$option]"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
elif [ $sshkey -eq 1 ]; then
|
|
|
|
if [ -r $option ]; then
|
|
|
|
sshkeyfile=$option
|
|
|
|
sshkey=0
|
|
|
|
else
|
|
|
|
echo "aborting mission. cannot read sshkeyfile. [$option]"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
elif [ $list -eq 1 ]; then
|
|
|
|
if [ -r $option ]; then
|
|
|
|
listfile=$option
|
|
|
|
list=0
|
|
|
|
else
|
|
|
|
echo "aborting mission. cannot read listfile. [$option]"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
if [[ $option =~ ^-.* ]]; then
|
|
|
|
echo "aborting mission. unknown option given. [$option]"
|
|
|
|
usage
|
|
|
|
exit 1
|
|
|
|
#TODO: what if source or destination is a number?
|
|
|
|
elif [ -z "${option//[0-9]/}" ]; then
|
|
|
|
versions="$option"
|
|
|
|
else
|
|
|
|
if [ -z "$sourcepath" ]; then
|
|
|
|
if [[ $option =~ .*@.* ]]; then
|
|
|
|
sourcepath="${option%/}/"
|
|
|
|
elif [[ $option =~ ^/.* ]]; then
|
|
|
|
sourcepath="${option%/}/"
|
|
|
|
else
|
|
|
|
sourcepath="$(pwd)/${option%/}/"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
if [ -z "$destinationpath" ]; then
|
|
|
|
if [[ $option =~ ^/.* ]]; then
|
|
|
|
destinationpath="${option%/}"
|
|
|
|
else
|
|
|
|
destinationpath="$(pwd)/${option%/}"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
if [ -r "$configfile" ]; then
|
|
|
|
source "$configfile"
|
|
|
|
fi
|
|
|
|
|
|
|
|
#read list if listfile is given
|
|
|
|
if [ -r "$listfile" ]; then
|
|
|
|
while read line; do
|
|
|
|
# find first letter
|
|
|
|
fletter=${line:0:1}
|
|
|
|
if [ -z $fletter ]; then
|
|
|
|
#skip line it's empty
|
|
|
|
:
|
|
|
|
elif [ $fletter = "#" ]; then
|
|
|
|
#skip line it's a comment
|
|
|
|
:
|
|
|
|
else
|
|
|
|
sourcepath=""
|
|
|
|
destinationpath=""
|
|
|
|
for option in $line; do
|
|
|
|
if [ -z "${option//[0-9]/}" ]; then
|
|
|
|
versions="$option"
|
|
|
|
else
|
|
|
|
if [ -z "$sourcepath" ]; then
|
|
|
|
if [[ $option =~ .*@.* ]]; then
|
|
|
|
sourcepath="${option%/}/"
|
|
|
|
elif [[ $option =~ ^/.* ]]; then
|
|
|
|
sourcepath="${option%/}/"
|
|
|
|
else
|
|
|
|
sourcepath="$(pwd)/${option%/}/"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
if [ -z "$destinationpath" ]; then
|
|
|
|
if [[ $option =~ ^/.* ]]; then
|
|
|
|
destinationpath="${option%/}"
|
|
|
|
else
|
|
|
|
destinationpath="$(pwd)/${option%/}"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
if ( preflight ); then
|
|
|
|
sshbackup
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
done < "$listfile"
|
|
|
|
else
|
|
|
|
if ( preflight ); then
|
|
|
|
sshbackup
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# **** end of script ****
|
|
|
|
exit 0
|