Я использую идеи, изложенные в этой статье, для создания инкрементных версионных резервных копий моих данных. Я в основном синхронизирую данные с текущей папкой в моем месте назначения резервной копии и затем создаю папку даты с жесткими ссылками на текущую папку. Я в конечном итоге с этим:

$ ls
...
2019-01-01_10-00-01
2019-01-02_10-00-01
...
2019-02-15_10-00-01
...
current

Работает отлично. Если мне когда-либо понадобится выполнить полное восстановление с определенной даты, я могу просто восстановить все из папки этой даты.

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

Я придумал это, и это работает, но мне интересно, есть ли более элегантный, стандартный способ сделать это.

#!/bin/bash

NOW=$(/bin/date +\%Y-\%m-\%d_\%H-\%M-\%S)

# the data that needs to be backed up
SOURCES=("/path/to/source 1" "/path/to/source 2")

# where it is going
DESTINATION="/path/to/backup"

# make sure the destination exists
mkdir -p "$DESTINATION"

# make sure there is a place to put the current data
mkdir -p "$DESTINATION/current"

# make sure there is a place to put the "combined" data
mkdir -p "$DESTINATION/combined"

# sync the data
rsync -v -a --delete "${SOURCES[@]}" "$DESTINATION/current"

# check if files were backed up
# any file with only one link is either new, and needs to have a hard link version
# or it wasn't fully backed up previously and needs a hard link version
if [[ $(find "$DESTINATION/current" -type f -links 1 | wc -l) -ne 0 ]] ; then
    # make a date folder backup using hard links
    cp -al "$DESTINATION/current" "$DESTINATION/$NOW"

    # make a combined view
    #  - find all files with 2 links
    #    - one link is to the file in the $DESTINATION/current
    #    - the other link is to the file in $DESTINATION/$NOW
    # - there should never be any files with only 1 hard link since the previous command
    #   is sure to have created a second link
    # - any files with more than 2 links were, hopefully, already covered during a previous iteration
    cd "$DESTINATION/current" && find * -type f -links 2 -print0 | while IFS= read -r -d $'\0' filePath
    do
        fileName="$(basename "$filePath")"
        fileFolder="$(dirname "$filePath")"

        # where the file will live in the combined folder
        # need to mirror the folder structure
        destinationFolder="$DESTINATION/combined/$fileFolder"
        mkdir -p "$destinationFolder"

        # make a hard link to it
        cp -al "$filePath" "$destinationFolder/$fileName.$NOW"
    done
fi

Код работает. После нескольких итераций, это то, что он создает:

Файлы в текущей папке (это "живая" копия исходных данных):

backup/current/source 1/001
backup/current/source 1/002
backup/current/source 1/003
backup/current/source 1/file 100
backup/current/source 1/folder/004
backup/current/source 2/006

Файлы в папках с определенной датой (файлы заметок из первой резервной копии содержат файлы, которых нет во второй, поскольку они были удалены):

backup/2019-01-15_23-08-02/source 1/001
backup/2019-01-15_23-08-02/source 1/002
backup/2019-01-15_23-08-02/source 1/003
backup/2019-01-15_23-08-02/source 1/file 100
backup/2019-01-15_23-08-02/source 1/folder/004
backup/2019-01-15_23-08-02/source 1/folder/005
backup/2019-01-15_23-08-02/source 2/006
backup/2019-01-15_23-08-02/source 2/007

backup/2019-01-15_23-09-00/source 1/001
backup/2019-01-15_23-09-00/source 1/002
backup/2019-01-15_23-09-00/source 1/003
backup/2019-01-15_23-09-00/source 1/file 100
backup/2019-01-15_23-09-00/source 1/folder/004
backup/2019-01-15_23-09-00/source 2/006

И это файлы в комбинированном представлении:

backup/combined/source 1/001.2019-01-15_23-08-02
backup/combined/source 1/002.2019-01-15_23-08-02
backup/combined/source 1/003.2019-01-15_23-08-02
backup/combined/source 1/003.2019-01-15_23-09-00
backup/combined/source 1/file 100.2019-01-15_23-08-02
backup/combined/source 1/folder/004.2019-01-15_23-08-02
backup/combined/source 1/folder/004.2019-01-15_23-09-00
backup/combined/source 1/folder/005.2019-01-15_23-08-02
backup/combined/source 2/006.2019-01-15_23-08-02
backup/combined/source 2/006.2019-01-15_23-09-00
backup/combined/source 2/007.2019-01-15_23-08-02

Таким образом, если мне нужно найти предыдущую версию source 1/folder/004 , мне просто нужно перейти в соответствующую папку в папке backup/combined/ (backup/combined/source 1/folder), и все файлы 004 есть , с добавленной отметкой даты / времени.

Есть ли лучший, более элегантный способ сделать это?

0