rsync
создаст только последний уровень иерархии каталогов на удаленном хосте, если он отсутствует.
Если у вас есть несколько отсутствующих уровней, вы можете предварить их такой командой:
$ ssh remote-host 'mkdir -p /data/static/maps/2019'
Затемrsync
сможет создать недостающий уровень 05
под ним.
Ваш сценарий завершится ошибкой, если какое-либо из имен файлов содержит символы новой строки. Синтаксический анализ 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, так что у вас должно работать, но я никогда не пользовался этой системой, поэтому не могу быть в этом уверен.