Bash скрипт для создания архива данных

от автора

На днях озадачился резевным копированием данных в облако. Нашёл подходящий сервис попробовал, и понял, что существует необходимость в сжатии бэкапа перед отправкой (думаю нет необходимости объяснять зачем). Не стал заморачиваться в поиске готовых решений и решил сам написать скромный скриптик для этой цели. Исходные файл или папка жмутся в .tar.xz с уровнем сжатия 9, что позволяет сохранить права и выдаёт хорошую компрессию на выходе (у меня снэпшот системы сжимается 4 раза). Результатом остался доволен, думаю для малого бизнеса, да и для личных целей многим пригодиться.

Возможности скрипта:

  • гибкая настройка
  • проверка на доступность ресурсов (источник, директория назначения, рабочая директория)
  • проверка на файл блокировки (предотвращает выполнение если источник еще создаётся)
  • вывод информации о сжатии (размер источника, размер архива, соотношение этих размеров)
  • логирование и дебагинг (вывод дополнительной информации о процессе выполнения)
  • возможность менять вывод (как в консоль и лог-файл, так и только в лог-файл)

Собственно сам скрипт (версия 2.0)

#!/bin/bash ################################################################################ ##    Bash script for file or directory compression                           ## ################################################################################ ## 1. Configuration variables ##  $work - Working directory. Lock and log files reside here. ##    @MUST have tail slash! @NOT mandatory! ##  $srcdir - Directory where the source resides. ##    @MUST have tail slash! ##  $srcname - Source, file or directory to compress. ##  $dest - Destination is where the archive will be placed. ##    @MUST have tail slash! ##  $archname - Archive file name. ##    [ example: "archive_$(date +"[%Y.%m.%d - %H:%M:%S]")" ] ##  $logname - Log file name. ##  $lockname - Lock file name. ##  $checklock - Check for lock file or not. ##     If you have condition(s) in which creation of an archive is not ##     recommended or fatal (e.g. while creating snapshot, directory must not ##     be tempered with in any way) and the process which is running prior to ##     archivation (rsnapshot, rsync, rdiff etc.), can create a lock file, ##     you must switch this check ON and fill out a name for a lock file, ##     to prevent integrity violation. ##     [ default: 0 ] { 0 = off, 1 = on } ##  $locksleep - How much time to wait until next try (in milliseconds). ##    [ default: 600 ] - 10 minutes. ##  $lockwait - How many tries before script stop. ##    [ default: 12 ] - Retry for 2 hours if $locksleep = 600 ##  $debug - Enable debugging or not. ##  $printtype - Set output to console and or log file. ##    [ default: "l" ] { "cl" = console & log, "l" = log only } ##  $timestamp - Timestamp format. ##    [ default: "[%Y.%m.%d - %H:%M:%S]" ] ##  $TIMEFORMAT - Output format for 'time' command. ##    [ default: "%E" ] ##  $compressor - Compressor and it's params. ##    [ default: "xz -T 4 -9 -c" ] ##  $archext - Archive extension, depending on $compressor setting. ##    [ default: ".tar.xz" ] ## ## 2. Functions ##  tstamp() - Prints timestamp. ##    [ example: "$(tstamp "[%Y.%m.%d - %H:%M:%S]")" ] ##    [ fallback: "${timestamp}" ] ##  bold() - Makes text bold. ##    [ example: "$(bold "TEST")" ] ##  printout() - Prints messages. ##    [ example: printout "Archive file name is: %s\n" "$(bold $arcname)" ] ##  checkconf() - Validates configuration. ##  checklock() - Checks for lock file. ##  execcomp() - Executes compression and assigns execution time to $exectime. ##  size() - Gets object size values. ##    @Takes two parameters, object and presentation format ##      (h - human readable, b - bytes)! ##    [ example: "$(size "$src" "b")" ] ##  compratio() - Gets compression ratio. ##    @Takes two parameters, source and archive! ##    [ example: "$(compratio "$src" "$archive")" ] ##  compinf() - Outputs compression info. ##    [ example: compinf $src $archive ] ################################################################################  ## =========================== ## ## Set configuration variables ## ## =========================== ## work="/tmp/" srcdir="/tmp/" srcname="testfile" dest=$work archname=$srcname logname="$srcname.log" lockname="$srcname.lock" checklock=1 locksleep=600 lockwait=12 debug=0 ## Do not change this variables if you don't know how! printtype="l" timestamp="[%Y.%m.%d - %H:%M:%S]" TIMEFORMAT="%E" compressor="xz -T 4 -9 -c" archext=".tar.xz"  ## ======================================= ## ## WARNING! Do not modify past this point! ## ## ======================================= ##  ## ---------------- ## ## Global variables ## ## ---------------- ## tb=$(tput bold) ## Bold text. tn=$(tput sgr0) ## Normal text. src=$srcdir$srcname ## Full path to source. archivefn=$archname$archext ## Archive file name and extension. archive=$dest$archname$archext ## Full path to archive. logfile=$work$logname ## Full path to log file. lockfile=$work$lockname ## Full path to lock file. confok=0 ## Configuration state. execute=0 ## Allow execution. exectime="" ## Compression execution time.  ## ------------- ## ## Initial setup ## ## ------------- ## exec 3>&1 1>>$logfile 2>&1 ## Modifies output.  ## --------- ## ## Functions ## ## --------- ## ## Sets timestamp. tstamp() { date +"${timestamp}"; } ## Makes text bold. bold() { echo "$tb$1$tn"; } ## Prints messages. printout() { [[ $printtype == "l" ]] && printf "$@" || (printf "$@" \  | tee /dev/fd/3); } ## Checks configuration. checkconf() {   # exec 2>/dev/null   pass=0   checkperm() {     if [[ ! -n ${2} ]]; then       [[ -r ${1} ]] && [[ -w ${1} ]] && echo 1 || echo 0;     else       case "$2" in         "f" ) [[ -f ${1} ]] && [[ -r ${1} ]] && [[ -w ${1} ]] && \          echo 1 || echo 0;;         "d" ) [[ -d ${1} ]] && [[ -r ${1} ]] && [[ -w ${1} ]] && \          echo 1 || echo 0;;         "fd" ) [[ -d ${1} ]] || [[ -f ${1} ]] && [[ -r ${1} ]] && \          [[ -w ${1} ]] && echo 1 || echo 0;;       esac     fi   }   status() { [[ $1 == 1 ]] && echo "$(bold "OK")" || echo "$(bold "NOT OK")"; }   ## Check working directory.   status=$(status "$(checkperm "$work" "d")")   pass=$(( pass+$(checkperm "$work" "d")))   [[ $debug == 1 ]] && printout \    "\t-> Working directory is %s and is set to: %s\n" "$status" "$(bold $work)"   ## Check source.   status=$(status "$(checkperm "$src" "fd")")   pass=$(( pass+$(checkperm "$src" "fd")))   [[ $debug == 1 ]] && printout "\t-> Source is %s and is set to: %s\n" \    "$status" "$(bold $src)"   ## Check destination.   status=$(status "$(checkperm "$dest" "d")")   pass=$(( pass+$(checkperm "$dest" "d")))   [[ $debug == 1 ]] && printout "\t-> Destination is %s and is set to: %s\n" \    "$status" "$(bold $dest)"   ## Display rest of the config.   [[ $debug == 1 ]] && printout "\t-> Archive is set to: %s\n" \    "$(bold $archivefn)"   [[ $debug == 1 ]] && printout "\t-> Log file is set to: %s\n" \    "$(bold $logname)"   [[ $debug == 1 ]] && [[ $checklock == 1 ]] && printout \   "\t-> Lock file is set to: %s\n" "$(bold $lockname)"   [[ $debug == 1 ]] && printout "\t-> Timestamp is set to: %s\n" \    "$(bold "$timestamp")"   [[ $debug == 1 ]] && printout "\t-> Compressor is set to: %s\n" \    "$(bold "$compressor")"   ## Validate config   if [ $pass == 3 ]; then     confok=1; [[ $debug == 1 ]] && printout "%s Configuration is %s!\n" \      "$(tstamp)" "$(bold "OK")"   else     printout "%s Configuration is %s, exiting...\n" "$(tstamp)" \      "$(bold "NOT OK")"; exit 1   fi } ## Checks for lock file. checklock() {   for ((i=1; i<=$lockwait; i++)); do     if [ -f ${lockfile} ]; then       [[ $debug == 1 ]] && printout \        "%s Lock file is in place, waiting... %s\n" "$(tstamp)" \         "$(bold "$i")"; sleep $locksleep     else       i=1000     fi     if [ $i == $lockwait ]; then       printout "%s Lock file is in place for to long, exiting...\n\n" "$(tstamp)"       exit 0     fi   done } ## Executes compression. execcomp() {   cd $srcdir || exit 1 ## Go to archive destination directory.   exectime=$( { time tar cf - $srcname | $compressor - > $archive; } 2>&1 ) } ## Gets object size values. size() {   [[ $2 == "b" ]] && du -bs "$1" | awk '{ print $1 }'   [[ $2 == "h" ]] && du -hs "$1" | awk '{ print $1 }' } ## Gets compression ratio. compratio() {   res=$(let res="$1/$2"; printf "%s" "$res"); printf "%.*f" 2 "$res" } ## Outputs compression info. compinf() {   printout "\t-> Source size: %s (%s bytes)\n" \    "$(bold "$(size "$1" "h")")" "$(bold "$(size "$1" "b")")"   printout "\t-> Archive size: %s (%s bytes)\n" \    "$(bold "$(size "$2" "h")")" "$(bold "$(size "$2" "b")")"   printout "\t-> Compression ratio: %s\n" \    "$(bold "$(compratio "$(size "$1" "b")" "$(size "$2" "b")")")" }  ## ---------- ## ## Initialize ## ## ---------- ## printout "%s Initializing...\n" "$(tstamp)" checkconf ## Check configuration. [[ $checklock == 1 ]] && checklock ## Check for lock file.  ## Check if the old archive file exists, if it does, delete it. if [ -f ${archive} ]; then   [[ $debug == 1 ]] && printout "%s Old archive exists, deleting...\n" \    "$(tstamp)"; rm -f ${archive}   if [ ! -f ${archive} ]; then     execute=1; [[ $debug == 1 ]] && printout \      "%s Old archive deleted, proceeding...\n" "$(tstamp)"   else     printout "%s %s Can't delete old archive file, exiting...\n" \      "$(tstamp)" "$(bold "WARNING!")"; exit 1   fi else   execute=1; [[ $debug == 1 ]] && printout \    "%s Old archive does not exist, proceeding...\n" "$(tstamp)" fi  ## Begin compression. if [ $execute == 1 ]; then   [[ $debug == 1 ]] && printout "%s Flag is set, executing...\n" \    "$(tstamp)"; execcomp   ## Check if archive file created.   if [ -f ${archive} ]; then     printout "%s Archive %s created in %s!\n" "$(tstamp)" "$(bold $archive)" \      "$(bold ${exectime})"     compinf $src $archive     # printout "%s Process has completed successfully!\n" "$(tstamp)"   else     printout "%s %s Archive file was NOT created, exiting...\n" \      "$(tstamp)" "$(bold "WARNING!")"; exit 1   fi else   printout "%s Flag is NOT set, exiting...\n" "$(tstamp)"; exit 1 fi  printout "\n"; exit 0 

P.S.
Тем, кому пригодился и есть желание доработать или сделать более элегантным, прошу на GitHub.

ссылка на оригинал статьи http://habrahabr.ru/post/266597/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *