Bash Backup. Моменты.

На днях пришлось писать скрипт для резервного копирования некоторых важных файлов на одном из серверов. Вся прелесть состояла в том, что резервирование должно было быть гибридным. Часть файлов нужно было хранить с накоплением, то есть при изменении файла, нужно было его копию в директории бекапа переименовать, а затем заново его сохранить в выше упомянутую директорию. Другие файлы нужно было хранить только в виде последней версии, то есть просто перезаписывать то, что уже лежит в бекапе.

В принципе, скрипты бекапа — вещь, с которой рано или поздно (безусловно лучше, если рано) сталкивается любой системный администратор (кстати, я на некоторое время из веб разработчиков переквалифицировался в Linux администратора =) ). Полностью весь скрипт приводить смысла не вижу, а вот непосредственно те его части, которые реализуют копирование, выношу на суд читателя.

Резервирование без накопления.

Нас интересуют только файлы и директории, символические ссылки и прочие чудеса — нет.

for ELEMENT in ${paths_o[@]}
    do
        if [ -e $BACKUP_PATH$ELEMENT ]; then
        if [ $ELEMENT -nt $BACKUP_PATH$ELEMENT ]; then
            if [ -s $ELEMENT ]; then
            if [ -h $ELEMENT ]; then
                continue;
            else
                if [ -d $ELEMENT ]; then
                mkdir -p "$BACKUP_TEMP$ELEMENT";
                cp -r $ELEMENT $BACKUP_TEMP$(dirname $ELEMENT);
                else
                if [ -f $ELEMENT ]; then
                    mkdir -p $BACKUP_TEMP$(dirname $ELEMENT);
                    cp $ELEMENT $BACKUP_TEMP$ELEMENT;
                else
                    continue;
                fi;
                fi;
            fi;
            fi;
        fi;
        else
        if [ -h $ELEMENT ]; then
            continue;
        else
            if [ -d $ELEMENT ]; then
            mkdir -p "$BACKUP_TEMP$ELEMENT";
            cp -r $ELEMENT $BACKUP_TEMP$(dirname $ELEMENT);
            else
            if [ -f $ELEMENT ]; then
                mkdir -p $BACKUP_TEMP$(dirname $ELEMENT);
                cp $ELEMENT $BACKUP_TEMP$ELEMENT;
            else
                continue;
            fi;
            fi;
        fi;
        fi;
    done;

Резервирование с накоплением

В данном случае используем рекурсивную процедуру. Принцип тот же — только файлы и каталоги.

walk_tree() {
    a=0;
    ls "$1" | while IFS= read i; 
    do
        if [ -L "$(dirname $1/$i)" ]; then
        continue;
        else
        if [ -d "$(dirname $1/$i)" ]; then
            a=$(($a+1));
                paths[$a]=$1/$i;
            walk_tree "$1/$i"
        else
                a=$(($a+1));
                paths[$a]=$i;
        fi;
        fi;
    done;

    for element in ${paths[@]}
    do
        if [ -L $element ]; then
                continue;
            else
            if [ -f $element ]; then
                    if [ -e $BACKUP_PATH$element ]; then
                        if [ $element -nt $BACKUP_PATH$element ]; then
                    if [ -s $element ]; then
                            mod=`stat -c %y $BACKUP_PATH$element | cut -d ' ' -f1`;
                            mkdir -p $BACKUP_TEMP$(dirname $element);
                        cp $BACKUP_PATH$element $BACKUP_PATH$element$mod;
                        cp $element $BACKUP_TEMP$(dirname $element); 
                        fi;
                fi;
                else
                mkdir -p $BACKUP_TEMP$(dirname $element);
                cp $element $BACKUP_TEMP$(dirname $element); 
                fi;
            else
                if [ -d $element ]; then
                    mkdir -p $BACKUP_TEMP$(dirname $element);
                    else
                    if [ -L $element ]; then
                        continue;
                    fi;
                    fi;
                fi; 
            fi;
        done;
}

p.s.

В целом работает, хотя идей для модификации и улучшения уже просто целый вагон. Надеюсь кому-нибудь пригодится.

Работа в режиме "backup"

no parameter

backup help

Bash Backup. Моменты.

Bash Backup. Моменты.: 13 комментариев

  1. Elvis:

    Скажите пожалуйста, что у вас за тема стоит — оформления окон и цветовая схема терминала? И что это за терминал?

    1. gwinn:

      RSync — весчь, но потребовали велосипед. Суть не в том, что это хороший способ работы с бекапами, а в том, как можно работать с файлами средствами Bash 🙂

  2. Zalm:

    man find
    сомнительно что тут только bash используется. вообще конечно кроме bash на первый взгляд тока cp/mkdir.
    но если на машине нет find то что там делает полный баш ?
    а вообще почитайте как работает backuppc, много идей для своих собственных скриптов почерпнете.

    1. gwinn:

      Backuppc — принято на заметку. 🙂
      А вообще я уже отвечал по поводу того, почему это так. Я пытался скорее показать на столько то, как реализовать бекап, сколько возможность работы с файлами в bash. В полном скрипте не только cp/mkdir, но разве использование системных команд в bash плохо?

      1. Zalm:

        да нормально, просто это все имело бы смысл если бы скрипт был на sh или с использованием busybox.

  3. Dream:

    Как реализовать, есть текстовый файл в котором имеются оприделённые строки:
    ——текст——
    * $text_in file /line1 ‘text’;
    * $text_in file /line2 ‘text’;
    * $text_in file /line3 ‘text’;
    $text_in file /line2 ‘text’;
    ——текст——

    Нам известно только начало строки $text_in как достать из файла строку которая начинается с $text_in и записать её в переменную, например, string???

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

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