bash скрипт для удаления предыдущей резервной копии - PullRequest
1 голос
/ 04 февраля 2020

Я настроил ежедневное задание cron для резервного копирования моего сервера.

При резервном копировании моей папки команда резервного копирования создает 2 файла: сам архив .tar.gz и файл .info. json как следующие:

-rw-r--r-- 1 root root     1617 Feb  2 16:17 20200202-161647.info.json
-rw-r--r-- 1 root root 48699726 Feb  2 16:17 20200202-161647.tar.gz
-rw-r--r-- 1 root root     1617 Feb  3 06:25 20200203-062501.info.json
-rw-r--r-- 1 root root 48737781 Feb  3 06:25 20200203-062501.tar.gz
-rw-r--r-- 1 root root     1618 Feb  4 06:25 20200204-062501.info.json
-rw-r--r-- 1 root root 48939569 Feb  4 06:25 20200204-062501.tar.gz

Как написать скрипт bash, который будет хранить только последние 2 архива и удалит все остальные резервные копии (targ.gz и info. json).

В этом примере это будет означать удаленные 20200204-062501.info. json и 20200204-062501.tar.gz.

Редактировать:

Я заменяю -name на - wholename в скрипте, но когда я его запускаю, он, очевидно, не имеет никаких эффектов. Старые архивы все еще там, и они не были удалены.

скрипт:

#!/bin/bash

DEBUG="";
DEBUG="echo DEBUG...";    #put last to safely debug without deleting files
keep=2;
for suffix in /home/archives .json .tar; do
    list=( $( find . -wholename "*$suffix" ) ); #allow for zero names
    if [ ${#list[@]} -gt $keep ]; then
        # delete all but last $keep oldest files
        ${DEBUG}rm -f "$( ls -tr "${list[@]}" | head -n-$keep )";
    fi
done

Редактировать 2:

если я запускаю скрипт @sorin, действительно ли он удаляет все, если я верю выводу скрипта?

Папка архива перед запуском скрипта:

https://pastebin.com/7WtwVHCK

Сценарий, который я запускаю:

find home/archives/ \( -name '*.json' -o -name '*.tar.gz' \) -print0 |\
    sort -zr |\
    sed -z '3,$p' | \
    xargs -0 echo rm -f

Вывод сценария:

https://pastebin.com/zd7a2zcq* 10 36 *

Редактировать 3:

Команда find /home/archives/ -daystart \( -name '*.json' -o -name '*.tar.gz' \) -mtime +1 -exec echo rm -f {} + работает и выполняет работу.

Помечено как решенное

Ответы [ 4 ]

1 голос
/ 08 февраля 2020

Если файл генерируется ежедневно, простой подход заключается в использовании условия поиска -mtime:

find /home/archives/ -daystart \( -name '*.json' -o -name '*.tar.gz' \) -mtime +1 -exec echo rm -f {} +
  • -daystart - используйте начало дня для сравнения модификации times
  • \( -name '*.json' -o -name '*.tar.gz' \) - выбрать файлы, заканчивающиеся на *.json или *.tar.gz
  • -mtime +1 - время модификации старше 24 часов (с начала дня)
  • -exec echo rm -f {} + - удалить файлы (удалите echo после тестирования и проверки того, что вам нужно)

Более простое решение, позволяющее избежать ls и его ошибок и не зависит от времени изменения файлов:

find /home/archives/ \( -name '*.json' -o -name '*.tar.gz' \) -print0 |\
    sort -zr |\
    sed -nz '3,$p' | \
    xargs -0 echo rm -f
  • \( -name '*.json' -o -name '*.tar.gz' \) - найти файлы, которые заканчиваются либо *.json, либо tar.gz
  • -print0 - выведите их через ноль
  • sort -zr - -z говорит sort использовать ноль в качестве разделителя строк, -r сортирует их в обратном порядке
  • sed -nz '3,$p' - -z то же самое как указано выше. '3,$p' - вывести строки между 3-м и концом ($)
  • xargs -0 echo rm -f - выполнить rm с переданными по конвейеру аргументами (убрать эхо после того, как вы проверили, и вы удовлетворены командой)

Примечание: не все sort и sed поддерживают -z, но большинство поддерживают. Если вы застряли в такой ситуации, возможно, вам придется использовать язык более высокого уровня

0 голосов
/ 04 февраля 2020

Если у вас меньше 10 файлов и они созданы в парах, то вы можете сделать что-то прямое, например:

files_to_delete=$(ls -tr1 | tail -n+3)
rm $files_to_delete

-tr1 сообщает команде ls для вывода списка файлов в обратном хронологическом порядке по времени модификации, каждое в одной строке.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *. строк).

Если у вас более 10 файлов, потребуется более сложное решение, или вам придется запускать его несколько раз.

0 голосов
/ 04 февраля 2020

Автоматическое c удаление может быть опасно для вашего психического состояния, если оно удаляет ненужные файлы или прерывает длинные сценарии на ранней стадии из-за непредвиденных ошибок. Скажите, когда в вашем примере меньше 1 + 2 файлов. Убедитесь, что сценарий не работает, если файлов вообще нет.

tdir=/home/archives/; #target dir DEBUG=""; DEBUG="echo DEBUG..."; #put last to safely debug without deleting files keep=2; for suffix in .json .tar; do list=( $( find "$tdir" -name "*$suffix" ) ); #allow for zero names if [ ${#list[@]} -gt $keep ]; then # delete all but last $keep oldest files ${DEBUG}rm -f "$( ls -tr "${list[@]}" | head -n-$keep )"; fi done

0 голосов
/ 04 февраля 2020

Найдите два последних файла в пути:

most_recent_json=$(ls -t *.json | head -1)
most_recent_tar_gz=$(ls -t *.tar.gz | head -1)

Удалите все остальное, игнорируя найденные последние файлы:

rm -i $(ls -I $most_recent_json -I $most_recent_tar_gz)
...