linux bash backup script
Incremental and rotating linux bash backup script which keeps original folder structure and does not overwrite unchanged files. Supports multiple backup destinations and filenames containing whitespaces and non-alphanumeric characters. Uses no compression.
Setup
edit
DAYS
,TARGET
andSOURCE
in backup.shif necessary, edit crontab parameters in install.sh
-
open terminal and run
chmod +x install.sh && ./install.sh
backup.sh
#!/bin/bash
DAYS=3
DESTINATION=(
'/media/'"$(whoami)"'/Backup_king'
)
SOURCE=(
'/home/'"$(whoami)"'/dev'
'/home/share/database'
'/home/share/txt'
'/home/share/web'
)
####################################################################################################
#(. )( .) (. )( .) (. )( .) (. )( .) (. )( .) (. )( .) (. )( .) (. )( .) (. )( .) (. )( .)#
####################################################################################################
copy_ () {
fil=$1
target=$2
tstamp=$(stat "$fil" -c %y | cut -d "." -f1 | sed -e 's/-//g; s/://; s/\ //g; s/:/\./')
cp "$fil" "$target""$fil"
echo COPY "$target""$fil"
touch -mt $tstamp "$target""$fil"
}
for TARGET in ${DESTINATION[@]} ; do
if [ ! -d "$TARGET" ]; then
logger "backup storage medium not found:" "$TARGET"
echo ERROR
break
fi
logger "backup is backing up files now:" "$TARGET"
#rm unneeded dates
folders_count=$(ls "$TARGET" | wc -l)
if (( $folders_count > $DAYS )); then
for rm_folder in $(ls "$TARGET" -t | tail -n $(( $folders_count - $DAYS )) );do
rm -r "$TARGET"'/'"$rm_folder"
done
fi
#mk todays dir
dir_='/'$(date +"%d-%m-%y")
if [ ! -d "$dir_" ];then
mkdir -p "$TARGET""$dir_"
fi
TARGET="$TARGET""$dir_"
#rm files from Backup
find "$TARGET" -type f | while read files;do
sourcefile=$(echo "$files"|sed 's|'$TARGET'||'g )
if [ ! -f "$sourcefile" ] ;then
rm "$TARGET""$sourcefile"
fi
done
#rm dirs from Backup
find "$TARGET" -type d| while read dir;do
sourcefile=$(echo "$dir"|sed 's|"$TARGET"||'g )
if [ ! -d "$sourcefile" ] ;then
rm -r "$TARGET""$sourcefile"
fi
done
for files in ${SOURCE[@]}; do
#mkdirs on Backup
find "$files" -type d | while read dir; do
if [ ! -d $"TARGET""$dir" ]; then
mkdir -p "$TARGET""$dir"
fi
done
#file operations
find "$files" -type f | while read file ; do
if [ ! -f "$TARGET""$file" ]; then
copy_ "$file" "$TARGET"
else
lm_o=$(stat "$file" -c %Y)
lm_b=$(stat "$TARGET""$file" -c %Y)
if [ $lm_o != $lm_b ] && [ $lm_o != $(( $lm_b + 1 )) ] && [ $lm_o != $(( $lm_b + 2 )) ];then
copy_ "$file" "$TARGET"
fi
fi
done
done #SOURCE
done #TARGET
install.sh
#!/bin/sh
mkdir -p '/home/'$(whoami)'/.backup'
cp 'backup.sh' '/home/'$(whoami)'/.backup'
chmod +x '/home/'$(whoami)'/.backup/backup.sh'
crontab -l > '/tmp/ccron'
if grep -q "#backup" "/tmp/ccron";then
echo "#backup cron job exists"
else
echo "adding new cron job"
echo '55 0-23/2 * * * /home/'$(whoami)'/.backup/backup.sh #backup' >> '/tmp/ccron'
crontab '/tmp/ccron'
fi
rm '/tmp/ccron'