Непрерывно обнаруживать новые файлы с помощью inotify-tools в нескольких каталогах рекурсивно

17

Я только что установил inotify-tools. Я хотел бы постоянно обнаруживать новые файлы с помощью notify-tools в нескольких каталогах и отправлять электронную почту с использованием postfix. Я, вероятно, могу обработать отправку электронной почты, используя постфиксную часть. Я просто пытаюсь выяснить лучший способ сделать это при попытке обнаружить новый файл (ы). Потому что иногда несколько файлов добавляются одновременно.

Дэвид Кастер
источник

Ответы:

39

inotifywait (часть inotify-tools ) - это правильный инструмент для достижения вашей цели, не важно, что несколько файлов создаются одновременно, он обнаружит их.

Вот пример скрипта:

#!/bin/sh
MONITORDIR="/path/to/the/dir/to/monitor/"
inotifywait -m -r -e create --format '%w%f' "${MONITORDIR}" | while read NEWFILE
do
        echo "This is the body of your mail" | mailx -s "File ${NEWFILE} has been created" "yourmail@addresshere.tld"
done

inotifywait будет использовать эти опции.

-m, чтобы следить за каталогом бесконечно, если вы не используете эту опцию, как только он обнаружит новый файл, сценарий завершится.

-r будет рекурсивно следить за файлами (если папок / файлов много, то обнаружение новых созданных файлов может занять некоторое время)

-e создать это возможность указать событие для мониторинга и в вашем случае следует создать , чтобы заботиться о новых файлах

--format "% w% f" распечатает файл в формате /complete/path/file.name

«$ {MONITORDIR}» - это переменная, содержащая путь для мониторинга, который мы определили ранее.

Таким образом, в случае создания нового файла, inotifywait обнаружит его и напечатает вывод (/complete/path/file.name) в канал и пока назначит этот вывод переменной NEWFILE .

Внутри цикла while вы увидите способ отправки почты на ваш адрес с помощью утилиты mailx, которая должна нормально работать с вашим локальным MTA (в вашем случае, Postfix).

Если вы хотите отслеживать несколько каталогов, inotifywait не позволяет этого, но у вас есть два варианта: создать скрипт для каждого каталога для мониторинга или создать функцию внутри скрипта, что-то вроде этого:

#!/bin/sh
MONITORDIR1="/path/to/the/dir/to/monitor1/"
MONITORDIR2="/path/to/the/dir/to/monitor2/"
MONITORDIRX="/path/to/the/dir/to/monitorx/"    

monitor() {
inotifywait -m -r -e create --format "%f" "$1" | while read NEWFILE
do
        echo "This is the body of your mail" | mailx -s "File ${NEWFILE} has been created" "yourmail@addresshere.tld"
done
}
monitor "$MONITORDIR1" &
monitor "$MONITORDIR2" &
monitor "$MONITORDIRX" &
sahsanu
источник
Я забыл добавить несколько объяснений, касающихся команд, используемых в примере скрипта, поэтому я отредактировал свой ответ ... Я также добавил скрипт на тот случай, если op хочет отслеживать несколько директорий. Что касается инструмента inotifywait, невозможно ответить на вопрос, не упомянув его, потому что op использует инструменты inotify. Кстати, я здесь новичок, поэтому мне нужно много узнать о сетевом этикете, так что, извините, если мой ответ совпадает с вашим, это не то, что я хочу, я просто хочу дать полный ответ для оп. Опять извините.
Сахсану
Нет проблем и добро пожаловать в SU. Изучение сетевого этикета обычно делается трудным путем, поскольку он нигде не определен.
harrymc
4
@sahsanu Я не согласен со всем этим "сетевым этикетом". Каждый человек отвечает на вопрос со своей точки зрения. Между ответами нет совпадений, и ответ не был переписан. Невозможно, чтобы ответы отличались таким образом, когда вопрос настолько специфичен. Большое спасибо, что нашли время, чтобы ответить на вопрос в деталях. Это помогло больше, чем вы знаете, для кого-то вроде меня, который только что узнал обо всем этом. Вы спасли меня бесчисленные часы.
Дэвид Кастер
1
@harrymc Netiquetta определяется здесь.
Дэвид Кастер
Сетевой этикет в развивающейся среде не может быть абсолютно определен. На этом сайте принято не дублировать ответы, если они не написаны плохо, и даже тогда рекомендуется исправлять их, а не редактировать. В демократическом обществе всегда ваше право не соглашаться. @sahsanu мог бы избежать моего замечания, сославшись на мой предыдущий ответ, показывая свой сценарий, который в любом случае получил бы ваше одобрение. Это то, что я бы сделал на его месте, и это мой сетевой этикет, которым, как я полагаю, я делюсь с другими (но не со всеми, конечно).
harrymc
8

Используйте inotifywait , например:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
        # do something with the file
    done

Для получения дополнительной информации и примеров см. Статью
Как использовать inotify-tools для запуска сценариев в событиях файловой системы .

harrymc
источник
1
Если кто-то использует это и преобразует переменные из чтения в верхний регистр, вы не сможете запускать некоторые команды в то время как. Это потому, что вы перезаписали бы переменную $ PATH.
Savageman
2
@Savageman Использование имен переменных в верхнем регистре для ваших собственных переменных настоятельно не рекомендуется именно по этой причине. Имена переменных в верхнем регистре зарезервированы для системного использования; Ваши собственные переменные должны использовать строчные буквы.
tripleee
@tripleee Спасибо за информацию, больше не буду использовать переменные в верхнем регистре :)
Savageman
0

Для нескольких каталогов вы можете сделать это:

#!/bin/bash


monitor() {
  inotifywait -m -r -e attrib --format "%w%f" --fromfile /etc/default/inotifywait | while read NEWFILE
  do
     echo "This is the body of your mail" | mailx -s "File ${NEWFILE} has been created" "yourmail@addresshere.tld"
  done
          }


monitor &

Вот пример списка папок в файле /etc/default/inotifywait /etc/default/inotifywait

/home/user1
/path/to/folder2/
/some/path/
Константин Франк
источник