Почему этот скрипт работает экономно?

rsync создаст только последний уровень иерархии каталогов на удаленном хосте, если он отсутствует.

Если у вас есть несколько отсутствующих уровней, вы можете предварить их такой командой:

$ ssh remote-host 'mkdir -p /data/static/maps/2019'
Затем

rsyncсможет создать недостающий уровень 05под ним.

0
27.03.2021, 16:50
1 ответ

Ваш сценарий завершится ошибкой, если какое-либо из имен файлов содержит символы новой строки. Синтаксический анализ lsочень плохая идея и, скорее всего, потерпит неудачу. Кроме того, ваш скрипт удалит только самый последний файл. Итак, если есть 100 файлов, у вас останется 99. Кажется, вы ожидаете, что он удалит все, кроме самых последних 4, но логика скрипта не работает таким образом.

Вот альтернативный подход, который может иметь дело с произвольными именами файлов и фактически удаляет все файлы, кроме самых последних 4:

#!/bin/bash

## avoid using CAPS for local variable names in shell scripts
backup_dir='/srv/dev-disk-by-uuid-9EE055CFE055ADF1/Backup dir/'
backup_file_path="/srv/dev-disk-by-uuid-9EE055CFE055ADF1/Backup dir/Backup [ashen] ($(date +%d-%m-%Y)).tar.gz"
server_dir='/var/lib/docker/volumes/49c9e5c53ea5b9c893c0a80117860da9b493484395c0$'
## This needs to be set to the number of files you want to keep plus one,
## so that we can use tail -n $max_backups below.
max_backups=5

tar -zcf "$BACKUP_FILE_PATH" "$SERVER_DIR" 

## delete all but the newest 4 tar.gz files in the
## backup directory
stat --printf '%Y %n\0' "$backup_dir"/*tar.gz |
  sort -rznk1,1 | tail -z -n +"$max_backups" |
  sed -z 's/^[0-9]* //' | xargs -0 rm -v

Работа здесь выполняется командой statи различными нисходящими трубами. Вот разбивка того, что делает команда:

  • stat --printf '%Y %n\0' "$backup_dir"/*tar.gz:печатает имя файла и возраст файла в секундах с момента появления всех .tar.gzфайлов в каталоге резервных копий. Чтобы иметь возможность обрабатывать имена файлов с переводом строки (\n), нам нужно заканчивать каждую запись NULL(\0). Вот как выглядит результат:

    $ stat --printf '%Y %n\0' * | tr '\0' '\n'
    1616867929./afile 5  tar.gz
    1616868565./file 10  tar.gz
    1616868560./file 1  tar.gz
    1616868561./file 2  tar.gz
    1616867927./file 3  tar.gz
    1616867928./file 4  tar.gz
    1616867930./file 6  tar.gz
    1616868562./file 7  tar.gz
    1616868563./file 8  tar.gz
    1616868564./file 9  tar.gz
    

Для этого примера я передал вывод в tr '\0' '\n', чтобы он был разборчивым, но на самом деле в конце каждой записи вместо этого стоит \0.

  • sort -rznk1,1:вывод statвыше передается в sort, который будет сортировать его численно (-n), в обратном порядке (-r), используя \0в качестве разделителя записей(-z)и учитывая только 1-й поле (-k1,1), которое является возрастом файла.

    Вывод выглядит так::

      $ stat --printf '%Y %n\0' "$backup_dir"/*tar.gz | 
          sort -rznk1,1 | tr '\0' '\n'
      1616868565./file 10  tar.gz
      1616868564./file 9  tar.gz
      1616868563./file 8  tar.gz
      1616868562./file 7  tar.gz
      1616868561./file 2  tar.gz
      1616868560./file 1  tar.gz
      1616867930./file 6  tar.gz
      1616867929./afile 5  tar.gz
      1616867928./file 4  tar.gz
      1616867927./file 3  tar.gz
    
  • tail -z -n +"$max_backups":команда tail -n +Xраспечатает последние записи, которые вы ей дали, начиная с записи X. Здесь X— это переменная $max_backups, поэтому эта переменная должна быть установлена ​​равной количеству файлов, которые вы хотите сохранить, плюс один. -zпозволяет tailработать с нулевыми -завершающимися записями.

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

       $ stat --printf '%Y %n\0' "$backup_dir"/*tar.gz  | sort -rznk1,1       
          | tail -z -n +5 | tr '\0' '\n'
      1616868561./file 2  tar.gz
      1616868560./file 1  tar.gz
      1616867930./file 6  tar.gz
      1616867929./afile 5  tar.gz
      1616867928./file 4  tar.gz
      1616867927./file 3  tar.gz
    
  • sed -z 's/^[0-9]* //':удаляет возраст файла, оставляя только имя. Еще раз, -zдолжен иметь дело с нулевыми -завершенными записями:

      $ stat --printf '%Y %n\0' "$backup_dir"/*tar.gz  | 
              sort -rznk1,1 | tail -z -n +5 | 
                  sed -z 's/^[0-9]* //' | tr '\0' '\n' 
     ./file 2  tar.gz
     ./file 1  tar.gz
     ./file 6  tar.gz
     ./afile 5  tar.gz
     ./file 4  tar.gz
     ./file 3  tar.gz
    
  • xargs -0 rm -v:последний шаг. Это приведет к удалению файлов и, опять же, -zпозволяет обрабатывать записи с нулевым завершением -.

ВАЖНО:сценарий предполагает, что вы используете инструменты GNU. Open Media Vault утверждает, что это Linux и работает под управлением Debian, так что у вас должно работать, но я никогда не пользовался этой системой, поэтому не могу быть в этом уверен.

1
28.04.2021, 22:56

Теги

Похожие вопросы