Skip to content

Auto Archive Files with ShellScripts

1. Introduction

We are going to introduce a shell script, which can auto archive folders on Linux.

2. Environment Requirements

  • OS: Linux with SHELL(sh), Other Unix maybe.
  • bash: Linux bash.

3. The Script

The Script can auto back configured folder to a configured destination:

################################ Global Config #################################
# Source Folder
__SERVICE_SOURCE__="${HOMEDIR}"
# Local Backup Folder
__HDD_PACK_BACK__="${HDD_BASE}"
__LOCAL_CLOUD_OD__="${HOMEDIR}/BackUp"
################################ Global Config #################################
################################# Service ######################################
declare -A SERVICES=(
    ["services"]="${__SERVICE_SOURCE__}/services,${LOGPATH}/services.log"
)
################################# Service ######################################

# log 1:MSG [2:LOG_PRITORITY]
log()
{
    __log_time__=$(date +"%b %e %T")
    if [ "${#}" -lt 1 ]; then
        false
    else
        __log_msg__="${1}"
    fi
    if [ "${#}" -lt 2 ]; then
        __log_prio__=7
    else
        __log_prio__=${2}
    fi
    logger -p ${__log_prio__} -t "$(basename ${0})" "${__log_msg__}"
    echo "${__log_time__} $(basename ${0}) (${__log_prio__}): ${__log_msg__}" >> ${__LOGFILE__}
}

# Encrypter 1:SOURCE_FILE 2:DEST_FOLDER [3:RECEIVER]
Encrypter()
{
    __receiver__="xxxxxxxxxxxxxxxx"
    if [ "${#}" -lt 2 ]; then
        false
    elif [ "${#}" -eq 3 ]; then
        __receiver__=${3}
    fi

    __encrypt_file__=${2}/${1##*/}.gpg

    log "dest encrypt file: ${__encrypt_file__}"

    # Delete exist NOT Uploaded file
    if [ -e ${__encrypt_file__} ]; then
        rm ${__encrypt_file__}
        log "Deleted exist file: ${__encrypt_file__} ......Done"
    fi

    # Encrypting packed files to DEST_FOLDER
    gpg -e -r ${__receiver__} -o ${__encrypt_file__} ${1}
    if [ -e ${__encrypt_file__} ]; then
        log "Encrypted...... ${__encrypt_file__} to __LOCAL_CLOUD_OD__ ......Done"
    fi
}

# Packer 1:SOURCE_FOLDER(whole path) 2:PACKED_DEST_FOLDER [3:ENCRYPT_DEST_FOLDER]
# If only use first 2 parameters, will not encrypt;
# If you wish to encrypt, you should use all 3 parameters.
Packer()
{
    # if end without "/"
    __service_name__=${1##*/}
    # if end with "/"
    if [[ ${__service_name__} == "" ]]; then 
        __service_name__="${1%%/}"
        __service_name__="${__service_name__##*/}"
    fi

    __tar_file__=${2}/${__service_name__}_$(date "+%Y%m%d").tar.gz

    # Packing
    if [ ! -e ${__tar_file__} ]; then
        # Packing folder
        tar -zcvf ${__tar_file__} ${1}
        log "Packed up ${__tar_file__} ......Done"

        # Encrypt from PACKED_DEST_FOLDER to ENCRYPT_DEST_FOLDER
        if [ -e ${__tar_file__} ]; then
            log "Save NOT encrypt file: ${__tar_file__} ......Done"
            # Check if need encryption
            if [ "${#}" -eq 3 ]; then
                Encrypter ${__tar_file__} ${3}
            fi
        fi
    fi
}

# PersonalFileBackUper 1:SOURCE_FOLDER 2:LOG_FILE
PersonalFileBackUper()
{
    __LOGFILE__=${2}

    # Pack BackUp and Cloud BackUp
    if [ $(date "+%d") == "01" ]; then
        Packer ${1} ${__HDD_PACK_BACK__} ${__LOCAL_CLOUD_OD__}
    else
        Packer ${1} ${__HDD_PACK_BACK__}
    fi
}

# CleanOldTarBackup 1:SERVICE_NAME
CleanOldTarBackup()
{
    __backup_versions__=$(ls -l ${__HDD_PACK_BACK__}/*${1}* | wc -l)
    if [ ${__backup_versions__} -gt 1 ]; then
        find ${__HDD_PACK_BACK__} -name "*${1}*" -mtime +6 -mtime -30 -exec rm {} \;
        __reserve_vers__=$(ls -l ${__HDD_PACK_BACK__}/*${1}* | wc -l)
        if [ ${__backup_versions__} -ne ${__reserve_vers__} ]; then
            log "Delete Old Backup files......Done"
        fi
    fi
}

main()
{
    # Backup Personal Service Data
    for service in "${!SERVICES[@]}"
    do
    {
        PersonalFileBackUper "${SERVICES[$service]%,*}" "${SERVICES[$service]#*,}"
        log "Archive ${service} OK."
        sleep 1

        # CleanUp Old Backup
        CleanOldTarBackup "${service}"
        sleep 1
    }
    done
}

# Calling main() funcion
main

4. Service Control with Systemd

[Unit]
Description=Backup files automatically
Wants=network-online.target
After=network-online.target

[Service]
User=root
Group=root
WorkingDirectory=/home/$USER
Environment="HOMEDIR=/home/$USER"
Environment="HDD_BASE=/Path/To/SSD"
Environment="LOGPATH=/var/log/ArchiveBackUp"
ExecStart=/bin/bash /Path/To/Script/ArchiveBackUp.sh

[Install]
WantedBy=multi-user.target
Some Environment should be configured in service file above: - HOMEDIR - HDD_BASE - LOGPATH

REF

[1].Execute-Scripts-on-Period-with-Systemd

[2].Shell字符串截取