Creating backups is an essential part of a users routine operations. Here are two scripts that a user can use, to manage backups of his home folder ~/:
#!/bin/sh
# Copyright (c) 2015-2020 Oliver Mahmoudi
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted providing that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
### backupuser - a user backup utility
# Functions:
# make_package_list
# create_backup
# backup_etc
# do_hook
# make_clean
# strip_trailing_slash
# scp_get_args
# scp_get_destination
# copy_backup_scp
# get_path_to_file
# get_filename
# delete_backup
# usage
# Variables:
WHO=`whoami` # == WHO=$(whoami)
DATE=$(date +%m.%d.%Y)
YEAR=$(date +%Y) # This year
TIME=$(date +%H-%M-%S)
FILENAME=${WHO}_${DATE}_${TIME}.tar.gz
ETC_NAME=etc_${DATE}_${TIME}.tar.gz
USER_REPORT_FILE=${WHO}_report
ETC_REPORT_FILE=etc_report
BACKUP_BASE=${HOME}/backups
BACKUP_DIR=${BACKUP_BASE}/${YEAR}
BACKUP_DIR_ETC=${BACKUP_BASE}/etc/${YEAR}
BU_CONTENTS= # contents of ${HOME}/.bu
SCP_DEST=
h_flag=0 # create backup in ${HOME}
j_flag=0 # ignore pre-backup processing
k_flag=0 # ignore post-backup processing
p_flag=0 # create installed packages list
r_flag=0 # do not log backup in user_report_file
s_flag=0 # scp flag
v_flag=0 # verbose flag
x_flag=0 # do not process ~/.bu/bu_excludes
#
# Save a list of the installed packages in root's home direcory if desired.
# Different operating systems use different package managers.
# Currently supported are: Linux's yum, dpkg and FreeBSD's pkg.
#
function make_package_list()
{
if [ -e "/usr/bin/yum" ] ; then
if [ $v_flag -eq 1 ] ; then
echo -n "Generating installed packages list..."
fi
yum list installed > ~/yum_list_installed
if [ $v_flag -eq 1 ] ; then
echo " done."
echo -n "Generating installed groups list..."
fi
yum grouplist > ~/yum_grouplist
if [ $v_flag -eq 1 ] ; then
echo " done."
echo -n "Generating installed repos list..."
fi
yum repolist all > ~/yum_repolist_all
if [ $v_flag -eq 1 ] ; then
echo " done."
echo
fi
elif [ -e "/usr/bin/dpkg" ] ; then
if [ $v_flag -eq 1 ] ; then
echo -n "Generating installed packages list..."
fi
dpkg -l > ~/installed_packages_list
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
else
echo "Unknown package manager."
fi
}
#
# Backup the user's home directoy. This is the main function.
#
function create_backup()
{
if [ $v_flag -eq 1 ] ; then
echo "Getting ready to backup ${WHO}'s home directory:"
fi
if [ "${WHO}" = "root" -a $p_flag -eq 1 ] ; then
make_package_list
fi
if [ ! -d ${BACKUP_DIR} ] ; then
if [ $v_flag -eq 1 ] ; then
echo -n "Your backup directory: ${BACKUP_DIR} doesn't seem to exist. Creating it..."
fi
mkdir -p ${BACKUP_DIR}
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
fi
# Invoke the do_hook function which checks for any extra files, that begin with
# any prefix other than the word 'post', in ${HOME}/.bu before the actual backup.
# The file bu_excludes, if found, will not be sourced.
if [ $j_flag -eq 0 ] ; then
do_hook "pre"
fi
# Move to the temporary backup directory /tmp or else ${BACKUP_DIR} if h_flag is set
if [ $v_flag -eq 1 -a $h_flag -eq 0 ] ; then
echo -n "Moving to temporary backup folder /tmp..."
elif [ $v_flag -eq 1 -a $h_flag -eq 1 ] ; then
echo -n "Moving to backup folder ${BACKUP_DIR}..."
fi
if [ $h_flag -eq 0 ] ; then
cd /tmp > /dev/null 2>&1
else
cd ${BACKUP_DIR} > /dev/null 2>&1
fi
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
# Create the backup
if [ -e "${HOME}/.bu/bu_excludes" -a $x_flag -eq 0 ] ; then
if [ $v_flag -eq 1 ] ; then
echo "The following files and folders will not be backed up:"
cat ${HOME}/.bu/bu_excludes
echo
if [ $h_flag -eq 0 ] ; then
echo -n "Creating backup in /tmp..."
else
echo -n "Creating backup in ${BACKUP_DIR}..."
fi
fi
tar -czf ${FILENAME} --exclude ${BACKUP_BASE} -X ${HOME}/.bu/bu_excludes ${HOME} > /dev/null 2>&1
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
else
if [ $v_flag -eq 1 -a $h_flag -eq 0 ] ; then
echo -n "Creating backup in /tmp..."
elif [ $v_flag -eq 1 -a $h_flag -eq 1 ] ; then
echo -n "Creating backup in ${BACKUP_DIR}..."
fi
tar -czf ${FILENAME} --exclude ${BACKUP_BASE} ${HOME} > /dev/null 2>&1
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
fi
# If $h_flag == 0, move the backup to the directory it is destined for, ${BACKUP_DIR}
# When being verbose, we here only need to report "echo done" to the user, when
# we are compiling the archive in /tmp.
if [ $v_flag -eq 1 -a $h_flag -eq 0 ] ; then
echo -n "Moving backup from /tmp to ${BACKUP_DIR}..."
fi
if [ $h_flag -eq 0 ] ; then
mv ${FILENAME} ${BACKUP_DIR} > /dev/null 2>&1
fi
if [ $v_flag -eq 1 -a $h_flag -eq 0 ] ; then
echo " done."
fi
# In case $h_flag == 1, we are already there, so therefore...
if [ $h_flag -eq 0 ] ; then
cd ${BACKUP_DIR} > /dev/null 2>&1
fi
# Test the backup
if [ $v_flag -eq 1 ] ; then
echo -n "Testing the backup..."
fi
gzip --test ${FILENAME} > /dev/null 2>&1
if [ $? -eq 0 ] ; then
if [ $v_flag -eq 1 ] ; then
echo ' OK!'
fi
else
echo "File: ${FILENAME} is corrupted."
rm -v ${FILENAME}
exit 1
fi
# Checksums
if [ $r_flag -eq 0 ] ; then
if [ $v_flag -eq 1 ] ; then
echo -n "Generating checksum in ${BACKUP_DIR}/${USER_REPORT_FILE}..."
fi
sha256sum ${FILENAME} >> ${USER_REPORT_FILE}
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
fi
# Call the do_hook function which checks for and sources any file, that
# begins with the word 'post' to process in ${HOME}/.bu after the backup.
if [ $k_flag -eq 0 ] ; then
do_hook "post"
fi
# Print out a status report.
echo 'Backup successful!'
echo "Your backup file is: ${BACKUP_DIR}/${FILENAME}"
}
#
# Make a backup of the /etc directory.
#
function backup_etc()
{
if [ "${WHO}" != "root" ] ; then
echo 'You need to be root to backup the /etc directory!'
exit 1
fi
if [ $v_flag -eq 1 ] ; then
echo "Getting ready to backup the /etc directory:"
fi
if [ ! -d ${BACKUP_DIR_ETC} ] ; then
if [ $v_flag -eq 1 ] ; then
echo -n "Backup directory: ${BACKUP_DIR_ETC} doesn't seem to exist. Creating it..."
fi
mkdir -p ${BACKUP_DIR_ETC}
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
fi
# Move to the temporary backup directory /tmp. Only root can initiate a backup of
# /etc so /tmp is always available.
if [ $v_flag -eq 1 ] ; then
echo -n "Moving to temporary backup folder /tmp..."
fi
cd /tmp > /dev/null 2>&1
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
if [ $v_flag -eq 1 ] ; then
echo -n "Creating the backup..."
fi
tar -czf ${ETC_NAME} /etc > /dev/null 2>&1
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
# Move the backup to the directory it is destined for
if [ $v_flag -eq 1 ] ; then
echo -n "Moving backup from /tmp to ${BACKUP_DIR_ETC}..."
fi
mv ${ETC_NAME} ${BACKUP_DIR_ETC} > /dev/null 2>&1
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
cd ${BACKUP_DIR_ETC} > /dev/null 2>&1
# test the backup
if [ $v_flag -eq 1 ] ; then
echo -n "Testing the backup..."
fi
gzip -t ${ETC_NAME} > /dev/null 2>&1
if [ $? -eq 0 ] ; then
if [ $v_flag -eq 1 ] ; then
echo ' OK!'
fi
else
echo "File: ${ETC_NAME} is corrupted."
rm -v ${ETC_NAME}
exit 1
fi
# Checksums
if [ $r_flag -eq 0 ] ; then
if [ $v_flag -eq 1 ] ; then
echo -n "Generating checksums in ${BACKUP_DIR_ETC}/${ETC_REPORT_FILE}..."
fi
sha256sum ${ETC_NAME} >> ${ETC_REPORT_FILE}
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
fi
# Print out a status report.
echo 'Backup successful!'
echo "/etc backup file is: ${BACKUP_DIR_ETC}/${ETC_NAME}"
}
#
# The modular hook function begings here. Check whether there are any files in the
# $HOME/.bu folder. If so, then source them.
#
function do_hook()
{
if [ ! -d ${HOME}/.bu ] ; then
return
fi
# Pre-Backup stage: Process any file, that begins with a prefix other then 'post'
# and is not the bu_excludes file.
if [ "$1" = "pre" ] ; then
cd $HOME/.bu
BU_CONTENTS=*
if [ -n "$BU_CONTENTS" ] ; then
if [ $v_flag -eq 1 ] ; then
echo "Sourcing pre-backup files from folder $HOME/.bu:"
fi
for i in $BU_CONTENTS
do
if [ "$i" = "*" ] ; then
if [ $v_flag -eq 1 ] ; then
echo "Done sourcing $HOME/.bu."
fi
return
fi
if [ "${i:0:4}" = "post" -o "${i}" = "bu_excludes" ] ; then
continue
fi
if [ $v_flag -eq 1 ] ; then
echo "Sourcing $HOME/.bu/$i"
fi
source ./$i
done
if [ $v_flag -eq 1 ] ; then
echo "Done sourcing $HOME/.bu."
fi
fi
# Post-Backup stage: Process any file, that begins with the prefix 'post'.
elif [ "$1" = "post" ] ; then
cd $HOME/.bu
BU_CONTENTS=*
if [ -n "$BU_CONTENTS" ] ; then
if [ $v_flag -eq 1 ] ; then
echo "Sourcing post-backup files from folder $HOME/.bu:"
fi
for i in $BU_CONTENTS
do
if [ "$i" = "*" ] ; then
if [ $v_flag -eq 1 ] ; then
echo "Done sourcing $HOME/.bu."
fi
return
fi
if [ ! "${i:0:4}" = "post" ] ; then
continue
fi
if [ $v_flag -eq 1 ] ; then
echo "Sourcing $HOME/.bu/$i"
fi
source ./$i
done
if [ $v_flag -eq 1 ] ; then
echo "Done sourcing $HOME/.bu."
fi
fi
fi
}
#
# Clean the users backup directory.
#
function make_clean()
{
local choice
# Confirm
echo "This will delete the entire contents of you backupfolder: ${BACKUP_BASE}"
echo -n "Are you sure? [yes or no]: "
read -t 30 choice # We got 30 seconds to make a choice
case $choice in
[Yy][Ee][Ss] | [Yy] ) # remove old files : >
rm -fvr ${BACKUP_BASE}/*
;;
[Nn][Oo] | [Nn] )
echo 'Aborted!'
exit 1
;;
*)
echo "Terminating."
exit 1
;;
esac
}
#
# Strip a trailing slash from given pathnames, i.e.
# /path/to/file/ becomes /path/to/file
#
function strip_trailing_slash()
{
local _length _strlen _last_char
_length=$(awk -v value=$1 'BEGIN {
n = length(value);
print n;
}')
_last_char=${1:$_strlen-1:1}
if [ "$_last_char" = "/" ] ; then
echo ${1:0:$_strlen-1}
else
echo $1
fi
}
#
# Copy the backup to another local device.
#
function copy_backup_local()
{
local _i
_i=$1
if [ -d $_i ] ; then
if [ -w $_i ] ; then
_i=$(strip_trailing_slash $_i)
if [ $v_flag -eq 1 ] ; then
echo -n "Copying backup to: $_i..."
fi
cp -i ${BACKUP_DIR}/${FILENAME} $_i
if [ $v_flag -eq 1 ] ; then
echo " done."
fi
else
echo "$_i is not writable."
fi
else
echo "$_i is not a directory."
fi
}
#
# Get the destination for scp. Passed via -s.
#
function scp_get_destination_path()
{
local _dest
_dest=$(awk -v value="$1" 'BEGIN {
n=split(value, a);
print a[n];
}')
echo $_dest
}
#
# Get the arguments (if any) for scp. Passed via -s.
#
function scp_get_arguments()
{
local _args
_args=$(awk -v value="$1" 'BEGIN {
args=""
n=split(value, a);
for(i = 1; i < n; i++)
args=args" "a[i];
print args;
}')
echo $_args
}
#
# Copy the backup via scp
#
function copy_backup_scp()
{
local _scp_args _scp_path _file
_file=$2
if [ $v_flag -eq 1 ] ; then
echo "Copying backup via scp:"
fi
_scp_args=$(scp_get_arguments "$1")
_scp_path=$(scp_get_destination_path "$1")
if [ ! -z "$_scp_args" ] ; then
scp $_scp_args $_file $_scp_path
else
scp $_file $_scp_path
fi
}
#
# Extract the path to a file: /path/to/file -> /path/to/
#
function get_path_to_file()
{
local _awkvar _ptf
# Get the left part of the last "/" aka path to file.
_ptf=$(awk -v _awkvar=$1 'BEGIN {
string = "";
n = split(_awkvar, a, "/");
for(i = 2; i < n; i++)
string = string"/"a[i];
string = string"/";
print string;
}')
echo $_ptf
}
#
# Extract the filename out of a full path: /path/to/file -> file
#
function get_filename()
{
local _awkvar _fn
# Get the right part of the last "/" aka filename.
_fn=$(awk -v _awkvar=$1 'BEGIN {
n = split(_awkvar, a, "/");
print a[n];
}')
echo $_fn
}
#
# Delete a backup
#
function delete_backup()
{
local _bu _choice _file _ln _nobs _rf _rf_flag
# Check for the existence of the backup that we seek to delete.
_bu=$(realpath $1)
if [ ! -f $_bu ]; then
echo "The backup: $_bu doesn't exist."
exit
fi
# Construct the report file and see if it exists in the target directory.
# If not, continue but set _rf_flag to 1
_rf_flag=0
_rf=$(get_path_to_file $_bu)${USER_REPORT_FILE}
if [ ! -f $_rf ]; then
_rf=$(get_path_to_file $_bu)${ETC_REPORT_FILE}
if [ ! -f $_rf ]; then
echo "The reportfile doesn't exist."
_rf_flag=1
fi
fi
# Check if the entry in our reportfile is unique. If so, get the line number.
if [ $_rf_flag -eq 0 ] ; then
_file=$(get_filename $_bu)
_nobs=$(cat $_rf | grep -c $_file)
if [ $_nobs -eq 0 ]; then
echo "No entry for: $_file in reportfile."
_rf_flag=1
elif [ $_nobs -eq 1 ]; then
_ln=$(cat $_rf | grep -n $_file)
else
# Not probable but still...
echo "Entry for: $_file in reportfile not unique."
_rf_flag=1
fi
fi
# Make sure and delete the backup. Otherwise abort.
echo "This will delete your backup: $_bu"
echo "Are you sure? [yes or no]: "
read -t 30 _choice # We got 30 seconds to make a choice
case $_choice in
[Yy][Ee][Ss] | [Yy] )
if [ $_rf_flag -eq 0 ] ; then
sed -i ${_ln%:*}d $_rf
fi
rm $_bu
exit 0
;;
[Nn][Oo] | [Nn] )
echo 'Aborted!'
exit 1
;;
*)
echo "Terminating."
exit 1
;;
esac
}
#
# usage function
#
function usage()
{
echo "usage:"
echo "backupuser [-hijkpruvx] [-d backup] [-s remote_server] [local_disks]"
echo "backupuser [-rv] [-s remote_server] etc [local_disks]"
echo "backupuser clean"
}
############################################################
##### Point of entry
while getopts ":d:hijkprs:uvx" opt ; do
case $opt in
d)
delete_backup $OPTARG
;;
h)
h_flag=1 # create archive in ${BACKUP_DIR}
;;
i)
j_flag=1 # no pre-backup processing in do_hook
k_flag=1 # no post-backup processing in do_hook
;;
j)
j_flag=1 # no pre-backup processing in do_hook
;;
k)
k_flag=1 # no post-backup processing in do_hook
;;
p)
p_flag=1 # create installed packages list flag
;;
r)
r_flag=1 # do not log the backup in report_file
;;
s)
s_flag=1 # scp flag
SCP_DEST=$OPTARG
;;
u)
usage
exit 0
;;
v)
v_flag=1 # be more verbose
;;
x)
x_flag=1 # do not process ~/.bu/bu_excludes
;;
\?)
echo "unkown flag: -$OPTARG."
usage
exit 1
;;
:)
echo "The -$OPTARG flag needs an argument"
usage
exit 1
;;
esac
done
shift $((OPTIND-1))
if [ "$1" = "clean" ] ; then
make_clean
echo 'Done!'
exit 0
elif [ "$1" = "etc" ] ; then
backup_etc
if [ $s_flag -eq 1 ] ; then
copy_backup_scp "$SCP_DEST" ${BACKUP_DIR_ETC}/${ETC_NAME}
fi
shift
else
create_backup
if [ $s_flag -eq 1 ] ; then
copy_backup_scp "$SCP_DEST" ${BACKUP_DIR}/${FILENAME}
fi
fi
for i in $*
do
copy_backup_local $i
done
echo 'Done!'
exit 0
The following script is meant to be run in the folder, to which the backup file has been copied to. It will generate the same reportfile, the backupuser utility creates when performing the backup. If the backups in the destination folder are not corrupted, then the contents of the reportfile will be equivalent to the one's in the user's home folder. To verify, the diff utility can be used.
Here is the source code for bu_check_files:
#!/bin/sh
# Copyright (c) 2015-2020 Oliver Mahmoudi
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted providing that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# Place this script in the folder to which you copy your backups and run it
# to:
# a) check the files for errors via gzip --test and
# b) generate their checksums.
#
# Later, the generated report file can be diffed with the original report file
# on the users hard drive.
# Variables:
WHO=$(whoami)
USER_REPORT_FILE=${WHO}_report
ETC_REPORT_FILE=etc_report
# Functions:
# create_report_file
# get_path_to_file
# get_filename
# delete_backup
create_report_file()
{
local _contents
if [ "$1" = "etc" ] ; then
_contents=etc*.tar.gz
: > ${ETC_REPORT_FILE}
else
_contents=*.tar.gz
: > ${USER_REPORT_FILE}
fi
for i in ${_contents} ; do
gzip --test ${i} > /dev/null 2>&1
if [ $? -eq 0 ] ; then
if [ "$1" = "etc" ] ; then
sha256sum ${i} >> ${ETC_REPORT_FILE}
else
sha256sum ${i} >> ${USER_REPORT_FILE}
fi
else
if [ "$1" = "etc" ] ; then
echo "File: ${i} is corrupted." >> ${ETC_REPORT_FILE}
else
echo "File: ${i} is corrupted." >> ${USER_REPORT_FILE}
fi
fi
done
}
get_path_to_file()
{
local _awkvar _ptf
# Get the left part of the last "/" aka path to file.
_ptf=$(awk -v _awkvar=$1 'BEGIN {
string = "";
n = split(_awkvar, a, "/");
for(i = 2; i < n; i++)
string = string"/"a[i];
string = string"/";
print string;
}')
echo $_ptf
}
get_filename()
{
local _awkvar _fn
# Get the right part of the last "/" aka filename.
_fn=$(awk -v _awkvar=$1 'BEGIN {
n = split(_awkvar, a, "/");
print a[n];
}')
echo $_fn
}
delete_backup()
{
local _bu _choice _file _ln _nobs _rf _rf_flag
# Check for the existence of the backup that we seek to delete.
_bu=$(realpath $1)
if [ ! -f $_bu ]; then
echo "The backup: $_bu doesn't exist."
exit
fi
# Construct the report file and see if it exists in the target directory.
# If not, continue but set _rf_flag to 1
_rf_flag=0
_rf=$(get_path_to_file $_bu)${USER_REPORT_FILE}
if [ ! -f $_rf ]; then
_rf=$(get_path_to_file $_bu)${ETC_REPORT_FILE}
if [ ! -f $_rf ]; then
echo "The reportfile doesn't exist."
_rf_flag=1
fi
fi
# Check if the entry in our reportfile is unique. If so, get the line number.
if [ $_rf_flag -eq 0 ] ; then
_file=$(get_filename $_bu)
_nobs=$(cat $_rf | grep -c $_file)
if [ $_nobs -eq 0 ]; then
echo "No entry for: $_file in reportfile."
_rf_flag=1
elif [ $_nobs -eq 1 ]; then
_ln=$(cat $_rf | grep -n $_file)
else
# Not probable but still...
echo "Entry for: $_file in reportfile not unique."
_rf_flag=1
fi
fi
# Make sure and delete the backup. Otherwise abort.
echo "This will delete your backup: $_bu"
echo "Are you sure? [yes or no]: "
read -t 30 _choice # We got 30 seconds to make a choice
case $_choice in
[Yy][Ee][Ss] | [Yy] )
if [ $_rf_flag -eq 0 ] ; then
sed -i ${_ln%:*}d $_rf
fi
rm $_bu
exit 0
;;
[Nn][Oo] | [Nn] )
echo 'Aborted!'
exit 1
;;
*)
echo "Terminating."
exit 1
;;
esac
}
usage()
{
echo "usage:"
echo "bu_check_files [-u] [-d backup]"
echo "bu_check_files etc"
}
### entry point
while getopts ":d:u" opt ; do
case $opt in
d)
delete_backup $OPTARG
;;
u)
usage
exit 0
;;
\?)
echo "unkown flag: -$OPTARG."
usage
exit 1
;;
:)
echo "The -$OPTARG flag needs an argument"
usage
exit 1
;;
esac
done
shift $((OPTIND-1))
if [ "$1" = "etc" ] ; then
create_report_file "etc"
else
create_report_file
fi
echo 'Done!'
exit 0
A gzipped tarball with the source code can be found here:
Version 1.1.1:
File: backupuser-1.1.1.tar.gz
sha256sum: afd15f9f2e0bac3b26394c0136be309cf41adf624de85f31b5d3e49127f82aaf
Alternatively you could clone the source code from github with:
git clone https://github.com/olimah/backupuser