我有一个应用程序,它以 XML“作业文件”的形式保存其数据,其中包含更大的 .tif 文件列表,其中包含应用程序生成的实际原始数据。通常,应用程序的用户只关心 XML 作业文件的位置:如果移动或重命名,.tif 文件列表将保持有效,因为它们的完整路径(通常位于专用于此目的的远程驱动器上)以对用户透明的方式记录在文件内。通过这种方式,作业文件可以保持较小,而不是膨胀到数十 GB。
但是,如果用户决定从操作系统中删除作业文件(即在 Windows 中从 cmd 窗口或 Windows 资源管理器中删除,或在 Linux 中从 bash shell 或 Nautilus 中删除),则可能会出现混乱,因为作业文件与其图像数据之间的链接被切断。与作业文件关联的图像文件将“孤立”,无法再从应用程序访问,但仍占用驱动器上的空间。
编写一个 shell 脚本来解析 XML 文件、识别其中列出的图像文件并删除它们,这很容易。确保运行此 shell 脚本自动地每次用户删除文件时都会运行该脚本,这可以一举解决我的问题。但是,我完全不知道如何配置操作系统,以便每次删除文件时都会运行该脚本,无论是在 Windows 还是 Linux 中。
有没有什么办法可以做到这一点?
答案1
有一个 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%
针对当前用户。
答案2
在 Linux 中,您可以使用如下简单的 bash 脚本:
#!/bin/bash
# Run code before and after prompting a user to delete a file
my_rm=/bin/rm
file1=$1
# Put the code you want to run pre-deletion here:
echo Running code before deleting ${file1}.
# Delete the file.
read -p "Are you sure you want to delete ${file1} (y/N): " decision
if [ "$decision" == "Y" ] || [ "$decision" == "y" ]; then
echo Deleting ${file1}...
$my_rm $file1
# Put the code you want to run post-deletion here:
echo Running code after deleting ${file1}.
else
echo No file deleted.
fi
# Put any cleanup code here:
echo Running cleanup code whether or not ${file1} was deleted.
exit
假设你调用脚本 my-delete.sh,你将使它可执行,
chmod +x my-delete.sh
并像这样运行它:
my-delete.sh jobfile.xml
现在,如果您想使用rm
删除文件,您可以将别名添加rm
到脚本:
alias rm='/path/to/my-delete.sh'
将上一行添加到您的 ~/.bashrc 或 ~/.profile 或适合您的系统的任何位置以使其永久生效。
如果您不想对除作业文件之外的文件运行额外代码,您可以添加文件名或文件类型的测试,并只对这些文件运行额外代码。以下脚本将特殊代码放入函数中,然后测试文件名以查看其是否包含模式“jobfile”。
#!/bin/bash
# Run code before and after prompting a user to delete a file
my_rm=/bin/rm
file1=$1
pattern='jobfile'
function rm_jobfile () {
# Put the code you want to run pre-deletion here:
echo Running code before deleting ${file1}.
# Delete the file.
read -p "Are you sure you want to delete ${file1} (y/N): " decision
if [ "$decision" == "Y" ] || [ "$decision" == "y" ]; then
echo Deleting ${file1}...
$my_rm $file1
# Put the code you want to run post-deletion here:
echo Running code after deleting ${file1}.
else
echo No file deleted.
fi
# Put any cleanup code here:
echo Running cleanup code whether or not ${file1} was deleted.
}
# If the file is a jobfile, run the function, otherwise just delete it.
if [[ $file1 =~ $pattern ]]; then
rm_jobfile $file1
else
$my_rm $file1
fi
exit
假设你已经创建了上面描述的别名,运行
rm jobfile1.xml
将执行 my-delete.sh 中的函数代码,但运行
rm something.txt
将不会。
由于 Microsoft Windows 现在包含 bash(我相信还有 Linux 内核),因此它也应该可以在那里运行,但我还没有测试过。我确信 powershell 脚本也可以从中改编。我不是 Windows 爱好者。希望这能有所帮助。