1

Я только что научился писать простые сценарии оболочки. Одним из них является то, что я просто дублирую определенные файлы в моей системе, которые имеют решающее значение для меня.

cp /dir/dir/file1 /samedir/samedir/file1.bak

Мои сценарии выполняются каждый раз, когда я подписываюсь в моей системе. Однако он всегда перезаписывает file1.bak . Я хотел бы найти способ сохранить все созданные файлы. Может быть что-то вроде file1(1).bak , file1(2).bak или что-то в этом роде.

VMS отлично подходит для определенных вещей, а именно, что каждый раз, когда кто-то пишет в файл с именем file.bak , он сохраняет все предыдущие версии, добавляя в конце файла «:», указывающий номер версии, т.е. file.bak:1 , file.bak:2 , file.bak:521 и т.д.

Мы использовали, чтобы избавиться от предыдущих версий с помощью команды purge file.bak 1-520 .

2 ответа2

2

Вы можете использовать некоторое программное обеспечение SCM (также называемое контролем версий), такое как git , mercurial или fossil .

Таким образом вы избежите огромного количества bak файлов в рабочем каталоге и будете отслеживать все предыдущие версии одновременно.

ИМХО самым простым из них будет ископаемое-scm. Это статически компилируемый одиночный файл, который может обрабатывать такие задания. (Кстати, созданный тем же программистом, который создал SQLite, так что ожидайте качества)

Ваш рабочий процесс может быть таким:

  1. cd в каталог, в котором нужно отслеживать файлы, и запустите репозиторий с помощью команды fossil init (он подготовит один файл базы данных).
  2. Скажите окаменелости, чтобы отслеживать конкретный каталог: fossil open
  3. Добавить файлы / каталоги рекурсивно в хранилище fossil addremove --dotfiles
  4. Сохранить текущий статус каталога в репозитории: fossil commit или если вы заботитесь о целостности файлов, то: fossil commit --sha1sum

Все последующие вызовы fossil - это просто fossil commit (если вам нужно добавить больше новых файлов или удалить некоторые из отслеживания, просто выполните перед фиксацией fossil addremove --dotfiles)

Таким образом, все изменения в файлах будут храниться во временной шкале и могут быть предварительно просмотрены или сравнены (diff) или извлечены (извлечены) из файла репозитория ether за файлом или полностью восстановят предыдущее состояние всего каталога.

Вы можете использовать fossil extras --dotfiles чтобы показать новые не отслеживаемые файлы или найти только те файлы, которые были изменены. fossil changes --abs-paths --sha1sum --header -v

Если вам нужно исключить некоторые файлы или каталог, ископаемые также поддерживают это.

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

Если вам нужно удалить некоторый контент из репозитория, для этого в fossil есть механизм, называемый "shunning".

0

Решение

Если вы не хотите использовать реальную систему управления версиями (как предложено @Alex & @Class Stacker), тогда следующий скрипт bash должен выполнить эту работу:

#!/bin/bash

#############
# Variables #
#############
FILE_LIST="foo.txt bar.doc"  # Space separated list of files to backup (include full path to file)
KEEP_OLD="5"  # How many previous versions to keep

#############
# Functions #
#############
function shift_backups {
        for num in $(seq $KEEP_OLD -1 1) ; do
                old_backup="$file.bak$num"
                if [[ -e $old_backup && $num == $KEEP_OLD ]] ; then
                                echo "    removing oldest file ($old_backup)"
                                rm -f $old_backup
                elif [[ -e $old_backup ]] ; then
                                new_name="$file.bak$(expr $num + 1)"
                                echo "    moving $old_backup to $new_name"
                                mv $old_backup $new_name
                fi
        done
}

################
# Backup Files #
################
for file in $FILE_LIST ; do
        count=1
        while [[ $count -le $KEEP_OLD ]] ; do
                backup_file="$file.bak$count"
                if [[ -e $backup_file ]] ; then
                        echo "$backup_file exists, shifting backups"
                        shift_backups
                        cp $file $backup_file
                        break
                else
                        cp $file $backup_file
                        break
                fi
                count=$(expr $count + 1)
        done
done

объяснение

Чтобы объяснить это, я разобью это и покажу вам логику.

переменные

  • Переменная FILE_LIST содержит разделенный пробелами список всех файлов, которые должны быть включены в резервную копию (убедитесь, что используются полные пути к файлам)
  • Переменная KEEP_OLD указывает, когда файлы .bak должны быть удалены. В примере установлено значение 5, означающее, что резервные копии не будут возвращаться дальше, чем 5 версий (при этом foo.txt.bak5 является самой старой версией)

Примечание. В зависимости от того, для скольких файлов вы это делаете, возможно, стоит изменить переменную FILE_LIST, чтобы ссылаться на файл и проходить по каждой строке. [Я не проверял эту идею]

функции

Функция shift_backups выполняет следующие действия:

  • Перебирает файлы резервных копий от самых старых до самых новых

    for num in $(seq $KEEP_OLD -1 1) ; do
    
  • Если файл резервной копии существует и считается самым старым, он будет удален

    if [[ -e $old_backup && $num == $KEEP_OLD ]]
    
  • Или, если файл резервной копии существует, он будет перенесен на backup number + 1

    elif [[ -e $old_backup ]]
    

Цикл резервного копирования

  • Итерация по каждому файлу в переменной FILE_LIST

     for file in $FILE_LIST ; do
    
  • Продолжайте цикл проверки резервных копий, пока значение count переменных равно 1

    while [[ $count -le $KEEP_OLD ]] ; do
    
  • Сохраните имя файла назначения в переменной

    backup_file="$file.bak$count"
    
  • Если файл резервной копии существует, вызывается функция shift_backups, а затем файл копируется (прерывая цикл while, когда это происходит)

    echo "$backup_file exists, shifting backups"
    shift_backups
    cp $file $backup_file
    break
    
  • Если файл резервной копии не существует, он только копируется и цикл while завершается

    else
    cp $file $backup_file
    break
    
  • Увеличивает count переменных

    count=$(expr $count + 1)
    

Выход

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

foo.txt.bak1 exists, shifting backups
    moving foo.txt.bak3 to foo.txt.bak4
    moving foo.txt.bak2 to foo.txt.bak3
    moving foo.txt.bak1 to foo.txt.bak2
bar.doc.bak1 exists, shifting backups
    moving bar.doc.bak3 to bar.doc.bak4
    moving bar.doc.bak2 to bar.doc.bak3
    moving bar.doc.bak1 to bar.doc.bak2

Если вам требуется, чтобы скрипт был тихим, удалите эхо, и он запустится так же.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .