Bash-скрипт: условное удаление старых файлов с сохранением последних копий.

Изменить: Хотя есть ответ от jeff-schaller , но он зависит от zsh ( который я собираюсь попробовать позже), поэтому я все же предпочел бы ответ, основанный на Bash . Спасибо.

Мне нравится создавать сценарий Bash для условного удаления старых файлов из каталога резервных копий.

Есть 2 условия для 2 отдельных резервных копий файлов:

1, сохранить последнюю копию Edge_Profile _ *. Tgz и удалить остальную часть Edge_Profile _ *. Tgz , только если они старше 5 дней .

2, Сохраните последнюю копию Firefox_Profile _ *. Tgz и удалите остальную часть Firefox_Profile _ *. Tgz , независимо от того, сколько им лет .

Вот моя бедная попытка изменить этот ответ AskUbuntu от @steeldriver: https://askubuntu.com/a/933098/928088

Скрипт:

#!/bin/bash

LOG_FILE="/home/admn/Cleanup.log"
TEMP_LOG="/tmp/Temp_Cleanup.log"

mv $LOG_FILE $TEMP_LOG

{

cd /home/admn/Downloads/Test;

echo ':::                                    :::'
echo
echo "Cleanup log:" `date`
echo

find /home/admn/Downloads/Test/Edge_Profile_*.tgz -type f \( -mtime +5 -printf 'Y\t' -o -printf 'N\t' \) -printf '%A@\t%p\0' |
    sort -zk2,2 | head -zn -1 | while read -r -d '' flag _ file; do \
        case "$flag" in 
            'Y') echo rm "$file" 
               ;; 
            *) echo "skipping $file (too new)"
               ;; 
        esac;
done

echo

find /home/admn/Downloads/Test/Firefox_Profile_*.tgz -type f \( -printf 'Y\t' -o -printf 'N\t' \) -printf '%A@\t%p\0' |
    sort -zk2,2 | head -zn -1 | while read -r -d '' flag _ file; do \
        case "$flag" in 
            'Y') echo rm "$file" 
               ;; 
            *) echo "skipping $file (too new)"
               ;; 
        esac        
done
echo
echo ':::                                    :::'

} &>> $LOG_FILE

cat $TEMP_LOG >>$LOG_FILE

exit;

Вывод в файл журнала с echo :

/usr/local/scripts/cleanup.sh

rm /home/admn/Downloads/Test/Edge_Profile_Jul_06_2021_00-35.tgz
rm /home/admn/Downloads/Test/Edge_Profile_Jul_07_2021_00-35.tgz
rm /home/admn/Downloads/Test/Edge_Profile_Jul_08_2021_00-35.tgz
rm /home/admn/Downloads/Test/Edge_Profile_Jul_09_2021_00-35.tgz
rm /home/admn/Downloads/Test/Edge_Profile_Jul_10_2021_00-35.tgz
rm /home/admn/Downloads/Test/Edge_Profile_Jul_11_2021_00-35.tgz
skipping /home/admn/Downloads/Test/Edge_Profile_Jul_12_2021_00-35.tgz (too new)
skipping /home/admn/Downloads/Test/Edge_Profile_Jul_13_2021_00-35.tgz (too new)
skipping /home/admn/Downloads/Test/Edge_Profile_Jul_14_2021_00-35.tgz (too new)
skipping /home/admn/Downloads/Test/Edge_Profile_Jul_15_2021_00-35.tgz (too new)
skipping /home/admn/Downloads/Test/Edge_Profile_Jul_16_2021_00-35.tgz (too new)

rm /home/admn/Downloads/Test/Firefox_Profile_Jul_01_2021_00-35.tgz
rm /home/admn/Downloads/Test/Firefox_Profile_Jul_02_2021_00-35.tgz
rm /home/admn/Downloads/Test/Firefox_Profile_Jul_03_2021_00-35.tgz
rm /home/admn/Downloads/Test/Firefox_Profile_Jul_04_2021_00-35.tgz
rm /home/admn/Downloads/Test/Firefox_Profile_Jul_05_2021_00-35.tgz
rm /home/admn/Downloads/Test/Firefox_Profile_Jul_06_2021_00-35.tgz
rm /home/admn/Downloads/Test/Firefox_Profile_Jul_07_2021_00-35.tgz

Вывод в файл журнала во время фактического выполнения сценария, без echo :

/home/admn/Downloads/cleanup.sh: line 24: skipping /home/admn/Downloads/Test/Edge_Profile_Jul_12_2021_00-35.tgz (too new): No such file or directory
/home/admn/Downloads/cleanup.sh: line 24: skipping /home/admn/Downloads/Test/Edge_Profile_Jul_13_2021_00-35.tgz (too new): No such file or directory
/home/admn/Downloads/cleanup.sh: line 24: skipping /home/admn/Downloads/Test/Edge_Profile_Jul_14_2021_00-35.tgz (too new): No such file or directory
/home/admn/Downloads/cleanup.sh: line 24: skipping /home/admn/Downloads/Test/Edge_Profile_Jul_15_2021_00-35.tgz (too new): No such file or directory
/home/admn/Downloads/cleanup.sh: line 24: skipping /home/admn/Downloads/Test/Edge_Profile_Jul_16_2021_00-35.tgz (too new): No such file or directory

Всего файлов в каталоге: 20 файлов

1, Edge_Profile_ *. tgz: С 6 по 17 июля: 12 файлов

2, Firefox_Profile_ *.tgz: С 1 июля по 08 июля: 8 файлов

Проблемы :

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

(2) Вывод в файл журнала:

Я бы предпочел тот же вывод в файле журнала, который я получаю с помощью echo , за исключением только имен файлов (не с полным путем), например:

rm Edge_Profile_Jul_11_2021_00-35.tgz

skipping Edge_Profile_Jul_12_2021_00-35.tgz (too new)

Настройка задания Cron:

Нужно ли мне определять / назначать пользователя для запуска скрипта?

crontab -e

45 0 * * * /usr/local/scripts/cleanup.sh && echo "Cleanup job completed on:" `date` >> /home/admn/jobs

ОС: Ubuntu MATE 21.04

Большое спасибо.

2
задан 19 July 2021 в 21:59

1 ответ

Управлять файлами в зависимости от времени их модификации намного проще в оболочке, которая позволяет вам обращаться к ним напрямую. zsh - одна из таких командных интерпретаторов. Просто sudo apt install zsh , чтобы установить его. Поскольку ваши файлы находятся в одном каталоге, этот ответ нерекурсивен. Сначала продемонстрируем более простой случай:

  • Чтобы сохранить последнюю копию Firefox_Profile _ *. Tgz и удалить остальные, независимо от их возраста:

     echo будет rm -v - Firefox_Profile _ *. Tgz (.om [2 , -1]) 
     

    Удаление эха будет частью , если оно выглядит правильно. Здесь используется квалификатор glob (подстановочный знак) внутри круглых скобок для выполнения трех действий:

    • выбирает только простые файлы (не каталоги, сокеты и т. Д.) С помощью .
    • упорядочить (отсортировать) файлы по времени их модификации, от самого нового к самому старому, с помощью om
    • выбрать часть результирующего списка, начиная со второго элемента до конца - пропуская первый (самый новый) файл. , с [2, -1]

    Если нет подходящих файлов, zsh остановится и выдаст сообщение «zsh: совпадений не найдено» и не выполнит rm .

  • Чтобы сохранить последнюю копию Edge_Profile _ *. Tgz и удалить остальные, только если они старше 5 дней, сначала мы берем самую последнюю:

     newest = (Edge_Profile _ *. Tgz (.om [1 ])) 
     

    ... а затем мы получаем те, которые старше пяти дней:

     старший = (Edge_Profile _ *. Tgz (.m + 5)) 
     

    Новая часть здесь - +5 на модификаторе m . Это выбирает файлы старше 5 дней. После этого мы убеждаемся, что самого нового нет в списке для удаления:

     remove = ("$ {(@) old: | newest}") 
     

    Новая часть здесь символ вычитания массива : | ; это описано в разделе Расширение параметров руководства zsh . Он выбирает элементы «старых», которых нет в «новейших». Наконец, мы удаляем этот список файлов:

     echo будет rm -v - "$ {remove [@]}" 
     
0
ответ дан 28 July 2021 в 11:17

Другие вопросы по тегам:

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