В этом материале мы аккумулируем знания, полученных из разных статей на канале и в результате получим скрипт, который будет очищать нужную нам директорию от старых файлов в конкретно заданный период. Постом убиваю двух зайцев - рассказываю вам интересные вещи и делаю себе жизнь проще.
Полезные и интересные материалы выходят каждый день. Чтобы не пропустить их, нужно подписаться на канал, если вы еще этого не сделали.
Сценарии использования
Скрипт, который мы напишем в итоге может применяться по-разному, самым часто используемым вариантом является применение на сервере. Случается так, что место на серверной машине заканчивается и после того, как изучаешь что «пожирает» его, то оказывается, что это директория с резервными копиями. Тот, кто настраивал бэкап не позаботился о том, чтобы старые копии сайта или базы данных удалялись по истечение определенного времени и они копились и копились, забирая место жесткого диска.
Второй сценарий использования напрямую связан с моей потребностью: так как я выпускаю заметки на канале практически каждый день, то в папке с загрузками скапливается приличное количество изображений, очищать которые вручную мне просто-напросто лень.
Суть работы скрипта
В определенное время скрипт будет «заглядывать» в нужную нам папку и находить там файлы определенного формата старше определенного времени, которые будет удалять. Чтобы написать этот скрипт нам будет необходим материал про поиск файлов и папок в Linux, который ранее выходил на канале.
Пишем скрипт
Писать мы будем так называемый bash-скрипт или сценарий командной строки, написанный для оболочки bash. По сути, скрипт будет содержать набор команд, которые нам нужно было ввести в терминале, чтобы получить указанный выше результат. Но мы не хотим делать это каждый раз, когда возникает потребность в очистке файлов, верно? Для автоматизации процедуры как раз-таки и понадобится скрипт. Будем работать в консольном текстовом редакторе, чтобы приблизить процесс написания максимально к боевому. Открываем терминал и создаем файл скрипта:
nvim <имя_скрипта>.sh
В качестве имени я выберу image_cleaner, вы вольны выбрать любое другое имя, для написания скрипта использовал консольный редактор Neovim (хочу рассказать про него в одной из следующих заметок), окончание .sh не обязательно, но обычно bash-скрипты определяют именно по нему.
В открывшемся окне консольного редактора пишем первую обязательную строку, которая указывает на то, что написанное ниже необходимо выполнять в консоли:
#!/bin/bash
Ощущаете себя программистом? Если нет, то это лишь потому, что мы еще не используем переменные. Исправляемся: второй строкой указываем место, в котором хотели выполнять очистку, в третьей задаем переменную, которая содержит количество дней, после которых файл нужно удалить.
dir="/home/jc/Загрузки"
expired_time="7"
Четвертой строкой мы зададим список нужных для удаления форматов файлов. Так как у меня изображения, то они могут быть с расширением jpeg, png, webp и так далее.
file_formats=("jpeg" "png" "jpg" "webp" "gif")
«Опытные программисты» обязательно напишут, что можно было использовать регулярные выражения, но сразу скажу, что мы опираемся только на материал предыдущих статей на канале, где я знакомил пользователей с командой find и ничего не говорил про регулярки. Поэтому воспользуемся списком (ну или массивом). Четырех пунктов мне должно хватить, так как не помню, что в папку попадали файлы с иными расширениями.
Ну, в общем-то, уже можете создавать резюме и рассылать в IT-компании! Хотя лучше погодите и давайте напишем самую главную часть скрипта - поиск и удаление старых файлов. Мы знаем, что поиск выполняется командой find и дополняется использование различных ключей и операторов. Не буду тянуть кота за причинные места, сразу покажу нужную команду, а потом разберем что она делает:
for ext in ${file_formats[@]}; do
find $dir -type f -name “*.$ext” -mtime +$expired_time -delete
done
Ух, ну и строчка же у нас получилась! На самом деле, ее содержимое очень просто для понимания. Давайте разбираться.
Первым делом мы пробегаем циклом for по нашему списку форматов и говорим, что на каждому круге хотим присваивать формат ключу ext. Для простоты представьте, что мы достаем из коробки бумажки с названиями расширений файлов.
Затем используем знакомую команду find и указываем ей ряд параметров:
- где искать - используем переменную dir, в которой хранится адрес нужной папки
- что искать - указываем, что нам нужны только файлы у которых имя может начинаться с чего угодно (символ звездочки), но заканчиваться оно должно каким-то значением из списка форматов (переменная ext)
Здесь мы используем так называемую «маску», задача которой - по максимуму сузить границы поиска и упростить его, одновременно сделав результат удаления безопасным для других файлов.
- критерий для поиска - ключ mtime используется чтобы найти что-то по времени изменения, в качестве строка указываем переменную expired_time равную, как помним, 7 дням.
- что делать с найденным - оператором delete говорим команде find, что найденные файлы нужно удалить.
Переменные в bash-скриптах задаются в начале файла, не должны включать пробелы между именами и знаком присваивания (=), а используются в коде с символом $ (знак доллара).
Итоговый файл скрипта выглядит следующим образом:
#!/bin/bash
dir="/home/jc/Загрузки"
expired_time="7"
file_formats=("jpeg" "png" "jpg" "webp" "gif")
for ext in ${file_formats[@]}; do
find $dir -type f -name "*.$ext" -mtime +$expired_time -delete
done
Ниже прикреплю демонстрацию того, как этот скрипт создавался. Для красоты разделил строки отступами.
Проверяем работу и автоматизируем запуск скрипта
Скрипт предлагаю разместить в какой-либо папке, откуда сложно удалить его случайно. На рабочих серверах мы создаем папку scripts, куда скидываем все нужное. Поступлю также и в этой ситуации, создав в Яндекс Диске папку со скриптами. Туда перенесу созданный скрипт и сделаю его исполняемым:
mkdir <место_до_нужной_папки>/scripts
mv image_cleaner.sh <путь_до_папки_scripts>
cd <путь_до_папки_scripts>; ls
sudo chmod +x image_cleaner.sh
Теперь нужно проверить работу скрипта, прежде чем его автоматизировать. Для этого, как вы понимаете, мне нужны файлы, скачанные более недели назад. Таких у меня не оказалось (очищал папку с загрузками вручную и понял, что нужно упростить эту процедуру, так и пришла идея поста), потому я просто скопировал в папку с загрузками картинки и чутка изменил скрипт, установив срок в 1 день вместо 7. Но это исключительно ради демонстрации, после верну старый срок.
Запускаем скрипт, не забывая указать точку и слэш перед названием (о том что это за точка я рассказывал в заметке прикрепленной выше)
./image_cleaner.sh
Скрипт отработал так, как и должен. Похвалили себя, идем дальше.
Для автоматизации будем использовать планировщик Cron, статью про этот замечательный инструмент можете найти по ссылке ниже.
Нам нужно, чтобы скрипт запускался каждую неделю, поэтому воспользуемся конструкцией @weekly, которая отвечает за это. Создаем задачу Cron для текущего пользователя:
crontab -e
@weekly <путь_до_скрипта_image_cleaner.sh>
После создания задачи Cron проверяем появилась ли она (на всякий случай) командой crontab -l
Вуа-ля! Мы получили автоматизированное решение по очистке старых файлов, которое работает как часы, есть и пить не требует.
Подведем итог
Созданный нами скрипт - один из самых легких среди тех, которые можно создавать для решения возникающих задач. Возможности BASH велики и порой в скриптах умудряются творить такое, что диву даешься.
У меня есть несколько идей по автоматизации повседневной рутины как для пользователя домашнего Linux-дистрибутива, так и для начинающего системного администратора, поэтому ждите ближайших постов.
Опытные же линуксоиды могут рассказать в комментариях о том, используют ли они связку «bash-скрипты + cron» для облегчения жизни и если да, то каким образом.
Чтобы не пропустить новые интересные и полезные материалы подпишитесь на канал, поддержите посты лайками, комментариями и репостами. Также не забываем про то, что можно подписаться на обновления Просто Код в Телеграме и получать уведомления о новых заметках.