Как да изпълним задача, когато нов файл е добавен към директория в Linux

Този урок ще ви покаже как да използвате събития на файловата система на Linux (уведомяване), за да получавате известия всеки път, когато файл се появи в директория. Можете да ги използвате като тригери за автоматизиране на общи задачи във вашата система.

Ще напишем скрипт, който наблюдава директория и действа върху нови файлове, които се добавят. Всеки файл се архивира и премества в друга директория веднага щом бъде открит. Скриптът използва подсистемата inotify чрез помощна програма, наречена inotify-tools. Но първо, нека инсталираме инструмента и да експериментираме.

Инсталиране на inotify-tools и gzip

Използвайте apt-get, за да инсталирате този пакет във вашата система, ако използвате Ubuntu или друга базирана на Debian дистрибуция. В други дистрибуции на Linux използвайте вместо това инструмента за управление на пакети на вашата Linux дистрибуция.

sudo apt-get install inotify-tools gzip

Експериментиране с inotify-инструменти

Нека започнем, като гледаме директория и видим какви събития започват, когато пристигнат нови файлове. Ще използваме инструмент, наречен inotifywatch, който е част от inotify-tools. Създайте нова директория, наречена „входящ“:

mkdir incoming

Започнете да гледате тази директория, като изпълните следната команда:

inotifywatch -v incoming

Това ще инструктира inotify да следи за всички събития на файловата система във „входящата“ директория. Опцията -v кара инструмента да отпечатва допълнителна информация за това, което прави. Не сме посочили опция за изчакване (-t ) и командата ще продължи да събира събития, докато не излезем с CTRL+C. В този момент нашият терминал трябва да изглежда така:

  Как да получите достъп до снимки и видеоклипове на вашия iPhone на Linux

Отворете нов прозорец на терминала (или раздел) и преминете към входящата директория. Използвайте командата за докосване, за да създадете нов файл с име „нов файл“.

cd incoming/
touch newfile

Сега се върнете към първия прозорец на терминала и спрете inotifywatch, като натиснете CTRL+C.

Таблица със събития ще бъде сервирана на конзолата, посочвайки един екземпляр на „create“, „open“, „attrib“ и „close_write“. Тези четири събития се случиха, когато използвахме докосване, за да създадем нов файл, зададохме неговите атрибути за достъп до файла, отворихме го, за да напишем нулев завършващ знак и след това го затворихме след това. Това са само част от множеството събития, които могат да бъдат наблюдавани във файлова система с inotify-tools. Можете да видите пълния списък на главната страница за inotifywatch.

За нашите цели се интересуваме само от две събития:

“create” – когато файл е създаден в целевата директория.
“moved_to” – когато файл е преместен от друго място в целевата директория.

Нека опитаме inotifywatch отново, но този път го инструктираме да наблюдава само тези две събития. Изпълнете тази команда в първия прозорец на терминала:

inotifywatch -v -e create -e moved_to incoming

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

touch incoming/created
echo Testing123 >> incoming/created
touch /tmp/created2
mv /tmp/created2 incoming/

Върнете се към първия прозорец на терминала и спрете inotifywatch, като натиснете CTRL+C. Ще видим следния изход:

  Как да играете Dead Space на Linux

Бяха отчетени само две събития: създаване на файл, наречен “created.txt” и преместване на съществуващ файл, наречен “created2.txt”. Всичко останало, като например промяната на „created.txt“, беше игнорирано.

Гледане на директория и изпълнение на задача

Сега, когато знаем какви събития да следваме, можем да използваме друг инструмент, наречен inotifywait, за да блокираме изпълнението, докато файлът не бъде създаден или преместен в нашата целева директория. Ще използваме същите аргументи, както направихме с inotifywatch и също така ще посочим как искаме името на файла да бъде форматирано за използване в нашата задача.

Преди да започнем, имаме нужда от директория за съхраняване на файлове, които вече са обработени. Създайте директория, наречена „обработено“:

mkdir processed

След това създайте нов скрипт, наречен “watch-incoming.sh” и добавете съдържанието, изброено по-долу:

#!/bin/bash

TARGET=~/incoming/
PROCESSED=~/processed/

inotifywait -m -e create -e moved_to --format "%f" $TARGET 
        | while read FILENAME
                do
                        echo Detected $FILENAME, moving and zipping
                        mv "$TARGET/$FILENAME" "$PROCESSED/$FILENAME"
                        gzip "$PROCESSED/$FILENAME"
                done

Скриптът изпълнява командата inotifywait с опцията -m. Това прави командния монитор да се променя за неопределено време. Всеки път, когато се открие ново събитие, името на файла се предава на командата read и се инжектира в променливата „FILENAME“. Изпълнява се блокът под цикъла while, в който файлът първо се премества в директорията „обработена“ и след това се архивира. Оригиналният файл се заменя с компресирания файл, а името на файла ще завършва на „.gz“.

  Как да използвате командата chroot в Linux

Нека дадем разрешения за изпълнение на този скрипт и да го стартираме от нашата домашна директория.

chmod u+x watch-incoming.sh
./watch-incoming.sh

Отворете втория прозорец на терминала и създайте нов файл във „входящата“ директория. Избройте съдържанието на директорията „входяща“ и „обработена“, за да видите резултатите от откритото събитие:

Суровият текстов файл, който копирахме във „входящата“ директория, беше открит от скрипта, копиран в „обработен“ и след това компресиран с gzip.

Вече можем да изпълняваме някои интересни задачи, след като сме в състояние да наблюдаваме нови файлове, пристигащи в директория. Например, бихме могли да добавим воден знак към файловете с изображения, да компресираме необработени видеоклипове във формат mp4 и дори да качваме всеки нов файл, който виждаме, в кофа на Amazon S3. Този скрипт е добра отправна точка за разгръщане на вашите собствени работни процеси и автоматизиране на общи задачи във вашата система.