Запустите команду оболочки, когда файл добавлен
У меня есть папка с именами изображений в моем Linux-окне.
Эта папка подключена к веб-сайту, и администратор сайта имеет возможность добавлять фотографии на этот сайт. Однако, когда изображение добавлено, я хочу, чтобы команда запускала изменение размера всех изображений в каталоге.
Короче говоря, я хочу знать, как я могу заставить сервер запускать определенную команду, когда новый файл добавляется в определенное место.
Ответы
Ответ 1
Я не знаю, как люди загружают контент в эту папку, но вы можете использовать что-то более низкотехнологичное, чем мониторинг каталога с помощью inotify.
Если протокол FTP, и у вас есть доступ к журналу FTP-сервера, я предлагаю настроить этот журнал для просмотра успешных загрузок. Такой подход, основанный на событиях, будет быстрее, надежнее и меньше нагрузки, чем опрос с традиционным cron, и более переносимым и более легким для отладки, чем с использованием inotify.
То, как вы справляетесь с этим, конечно, зависит от вашего FTP-сервера. У меня один работает vsftpd, чьи журналы включают в себя такие строки:
Fri May 25 07:36:02 2012 [pid 94378] [joe] OK LOGIN: Client "10.8.7.16"
Fri May 25 07:36:12 2012 [pid 94380] [joe] OK UPLOAD: Client "10.8.7.16", "/path/to/file.zip", 8395136 bytes, 845.75Kbyte/sec
Fri May 25 07:36:12 2012 [pid 94380] [joe] OK CHMOD: Client "10.8.7.16", "/path/to/file.zip 644"
Строка UPLOAD
добавляется только тогда, когда vsftpd успешно сохранил файл. Вы можете разобрать это в оболочке script следующим образом:
#!/bin/sh
tail -F /var/log/vsftpd.log | while read line; do
if echo "$line" | grep -q 'OK UPLOAD:'; then
filename=$(echo "$line" | cut -d, -f2)
if [ -s "$filename" ]; then
# do something with $filename
fi
fi
done
Если вы используете инструмент загрузки HTTP, посмотрите, есть ли у этого инструмента файл текстового журнала, который он использует для записи входящих файлов. Если он не учитывает добавление к нему какой-то функции журнала, поэтому он будет создавать журналы, которые вы можете tail
.
Ответ 2
Как пояснил Джон, API-интерфейс inotify
является отправной точкой, однако вам могут быть интересны некоторые инструменты, которые используют этот API для выполнения задач уведомления о файлах:
Например incron, который может использоваться для запуска cron-подобных задач при обнаружении изменений файла или каталога.
Или inotify-tools, который представляет собой набор инструментов командной строки, которые можно использовать для создания собственных оболочки уведомлений файла script.
Если вы посмотрите внизу патча Wiki для инструментов inotify, вы увидите ссылки на еще больше инструментов и поддержку языков более высокого уровня, таких как Python, Perl или Ruby (пример кода).
Ответ 3
Возможно, вы захотите посмотреть inotify
API-интерфейс inotify предоставляет механизм для мониторинга событий файловой системы. Inotify может использоваться для мониторинга отдельных файлов или для контроля каталогов. Когда каталог контролируется, inotify будет возвращать события для самого каталога и для файлов внутри каталога.
Ответ 4
Использование работы ghotis
Вот что я сделал, чтобы получить свободное пространство для пользователей:
#!/bin/bash
tail -F -n 1 /var/log/vsftpd.log | while read line; do
if echo "$line" | grep -q 'OK LOGIN:'; then
pid=$(sed 's/.*\[\([^]]*\)\].*/\1/g' <<< "$line")
#the operator '<<<' doesnt exist in dash so use bash
if [[ $pid != *"pid"* ]]; then
echo -e "Disk 1: Contains Games:\n" > /home/vftp/"$pid"/FreeSpace.txt; df -h /media/Disk1/ >> /home/vftp/"$pid"/FreeSpace.txt
echo -e "\r\n\r\nIn order to read this properly you need to use a text editor that can read *nix format files" >> /home/vftp/"$pid"/FreeSpace.txt
fi
echo "checked"
# awk '{ sub("\r$", ""); print }' /home/vftp/"$pid"/FreeSpace.txt > /home/vftp/"$pid"/FreeSpace.txt
fi
done
Ответ 5
Если файл добавлен через HTTP-загрузку, и если ваш сервер является apache, вы можете проверить mod_security.
Он позволяет запускать script для каждой загрузки, сделанной через HTTP POST.
Ответ 6
#!/bin/bash
tail -F -n0 /var/log/vsftpd.log | while read line; do
if echo "$line" | grep -q 'OK UPLOAD:'; then
filename=$(echo $line | cut -d, -f2 |awk '{print $1}')
filename="${filename%\"}"
filename="${filename#\"}"
#sleep 1s
if [ -s $filename ]; then
# do something with $filename
echo $filename
fi
fi
done