Как я могу заставить скрипт запускаться при удалении файла?

267
Eos Pengwern

У меня есть приложение, которое сохраняет свои данные в виде «рабочих файлов» XML, которые содержат списки гораздо больших файлов .tif, которые содержат фактические необработанные данные, которые генерирует приложение. Как правило, пользователь приложения заботится только о местонахождении файла задания XML: если он будет перемещен или переименован, список файлов .tif останется действительным, поскольку полный путь к ним (который часто будет на удаленном диске) выделенный для этой цели) записывается внутри файла таким образом, что является прозрачным для пользователя. При таком подходе размер рабочего файла может быть небольшим, а не увеличиваться до десятков гигабайт.

Однако, если пользователь решает удалить файл задания из ОС (то есть из окна cmd или проводника Windows в Windows, или из оболочки bash или Nautilus в Linux), возникает опасность возникновения хаоса из-за связи между рабочий файл и данные его изображения были разорваны. Файлы изображений, связанные с файлом задания, будут «осиротевшими», более не доступны из приложения, но, тем не менее, по-прежнему занимают место на диске.

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

Есть ли способ сделать это?

1
вы можете использовать наблюдателей для реализации подхода к событиям и ответам, но вам придется написать отдельные версии для Windows и Linux, так как они работают совершенно по-разному. для windows я бы написал приложение .net, но этот скрипт powershell должен делать то же самое: https://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b Frank Thomas 8 лет назад 1
В Linux можно использовать [inotifywait] (http://linux.die.net/man/1/inotifywait). John1024 8 лет назад 0
Спасибо; однако, насколько я вижу, как класс FileSystemWatcher в .Net, так и API inotify в Linux заставляют отправлять сигналы _after_, файл удален, и к тому времени будет слишком поздно читать таблицу файлов изображений, содержащихся в нем. (если я не могу временно восстановить его из корзины). Я надеялся найти способ вызвать сценарий после того, как пользователь запросит удаление, но _before_ фактическое удаление происходит (немного похоже на деструктор C ++), так что содержимое файла, который будет удален все еще можно прочитать. Eos Pengwern 8 лет назад 0
Для этого вам придется подключить Windows API. На самом деле я не уверен, что это возможно, но вы хотите прервать стандартное поведение API, поэтому, если они не подберут вас, это будет очень трудно осуществить. Frank Thomas 8 лет назад 0

1 ответ на вопрос

0
Paul

Существует порт Windows, inotifywaitкак указано в комментариях, под названиемinotify-win

Скачать:

https://github.com/thekid/inotify-win/archive/master.zip

Обобщение:

%WINDIR%\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:inotifywait.exe src\*.cs 

Использование:

$ inotifywait.exe Usage: inotifywait [options] path [...]  Options: -r/--recursive: Recursively watch all files and subdirectories inside path -m/--monitor: Keep running until killed (e.g. via Ctrl+C) -q/--quiet: Do not output information about actions -e/--event list: Events (create, modify, delete, move) to watch,  comma-separated. Default: all --format format: Format string for output. --exclude: Do not process any events whose filename matches the specified regex --excludei: Ditto, case-insensitive  Formats: %e : Event name %f : File name %w : Path name %T : Current date and time 

Редактировать:

Если вы хотите избежать злонамеренных действий, решение может быть icaclsв файловой системе NTFS

Чтобы защитить файл от удаления:

icacls file.ext /deny Everyone:(DE) rem To reset icacls file.ext /reset 

Чтобы защитить папку с ее содержимым, используйте:

icacls folder /deny Everyone:(OI)(CI)(DE,DC) rem To reset icacls folder /reset 

*S-1-1-0вместо того, чтобы не зависеть от Everyoneязыка, а также %USERNAME%для текущего пользователя.

спасибо, но, пожалуйста, смотрите мой комментарий под оригинальным вопросом. Eos Pengwern 8 лет назад 0

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