This is my first attempt at scripting with bash. I am running Ubuntu server, so I don't get to use all the gui back ups out there. Besides, tar works fine for personal use. Please let me know of any improvements and why. #!/bin/bash # PURPOSE: # TO BACK UP ALL FILES AND FOLDERS FROM A GIVEN DIRECTORY # Directory to back up is set with the constant BACK_UP_LOCATION # Directory to save the back up to is /IT/backup/ and is set with the constant BACK_UP_DIR # Directory to save the log files to is /IT/backup/log/ and is set by changing the tail end of the constant BACK_UP_LOG_DIR # Obviously additional directories can be added to the back up by adding additional constants and incorporating that tar command(s) to go with them # Written by Rowland Holden # This script could have used the find command to delete the old files # but that wouldn't have allowed for the logging of each deleted file so # I chose to do it the long way to get the logging I wanted # File Info: tar-share-backup @ cron.daily # Set constants NOW=$(date +%m-%d-%Y) BACK_UP_DIR="IT/backup/" BACK_UP_PATH="${BACK_UP_DIR}ShareBackup${NOW}" BACK_UP_LOG_DIR="${BACK_UP_DIR}log/" BACK_UP_LOG_PATH="${BACK_UP_LOG_DIR}ShareBackupLog${NOW}" BACK_UP_LOCATION="srv/share/" cd / # check if script is already running write_pid_running_error () { local errorText="${0} is already running: canceling backup operation" if [[ -f "${BACK_UP_LOG_PATH}" ]]; then echo "" >> "${BACK_UP_LOG_PATH}" echo "${errorText}" >> "${BACK_UP_LOG_PATH}" else echo "${errorText}" > "${BACK_UP_LOG_PATH}" fi } for pid in $(pidof -x `basename $0`); do if [[ $pid != $$ ]]; then write_pid_running_error exit 1 fi done # Check to see if the back up file already exists and write an error in the log if it does # write error to log file if back up file exists write_file_exists_error () { local errorText="backup file already exists: canceling backup operation" if [[ -f "${BACK_UP_LOG_PATH}" ]]; then echo "" >> "${BACK_UP_LOG_PATH}" echo "${errorText}" >> "${BACK_UP_LOG_PATH}" else echo "${errorText}" > "${BACK_UP_LOG_PATH}" fi } # check to see if th back up tar file already exists - if so let the user know in the log and exit - # do not continue because we don't know if the user wants to rm the file or not check_file () { if [[ -f "${BACK_UP_PATH}.tar.gz" ]]; then write_file_exists_error exit 1 fi } del_files () { local filepath="${1}" local modDate="${2}" local file="${3}" local dir="${4}" local delCutOffDate=$(date -d "$date -7 days" +%m-%d-%Y) # sets date to 7 days ago if [[ -f "${filepath}" ]]; then # make sure $file is an actual file and not a directory if [[ "${modDate}" -ot "${delCutOffDate}" ]]; then # Compares the file modified date to the cut off date for deletion - anything older than 7 days echo " ${file} deleted from ${dir}" >> "${BACK_UP_LOG_PATH}" echo " ModDate: ${modDate}" >> "${BACK_UP_LOG_PATH}" echo " Cut Off: ${delCutOffDate}" >> "${BACK_UP_LOG_PATH}" echo " test: ${modDate} -ot ${delCustOffDate}" >> "${BACK_UP_LOG_PATH}" rm "${filepath}" >> "${BACK_UP_LOG_PATH}" fi fi } cycle_files () { local files=("$@") local dir="${files[-1]}" # $ is set on the number of arguments, so this wouldn't be $1, it would be $ whatever the last index in the argument array is # This is because the number of files are dynamic, making the array indexing dynamic. making this way the best to obtain the dir we want unset 'files[-1]' # remove the directory as filepath prefixes the file with the directory - prefixing a directory to a directory will throw an error for file in "${files[@]}"; do # for each file in the current directory do the following loop filepath="${dir}${file}" # prefix the filename with the directory path for file manipulation modDate=$(date -r "${filepath}" +%m-%d-%Y) # Gets modified date of a file del_files "${filepath}" "${modDate}" "${file}" "${dir}" done } cycle_dirs () { local dirs=("$@") for dir in "${dirs[@]}"; do # for each directory do the following loop files=($(ls "${dir}")) # list all files in $dir and put them in an array echo "Enterying: ${dir}" >> "${BACK_UP_LOG_PATH}" cycle_files "${files[@]}" "${dir}" done } delete_old_files () { echo "" >> "${BACK_UP_LOG_PATH}" echo "" >> "${BACK_UP_LOG_PATH}" echo "The folowing files were deleted:" >> "${BACK_UP_LOG_PATH}" echo "" >> "${BACK_UP_LOG_PATH}" dirs=( "${BACK_UP_DIR}" "${BACK_UP_LOG_DIR}" ) # create an array of directories to cycle through for deleting old back up and log files cycle_dirs "${dirs[@]}" } check_file # Back up files echo "The following files were backed up:" > "${BACK_UP_LOG_PATH}" # if we have gotten this far we have a clean back up file so lets also do a clean log echo "" >> "${BACK_UP_LOG_PATH}" tar -czvf "${BACK_UP_PATH}.tar.gz" "${BACK_UP_LOCATION}" >> "${BACK_UP_LOG_PATH}" # Delete old log and back up files delete_old_files exit 0