我见过这个答案:
您应该考虑使用 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
上面的脚本监视目录以创建任何类型的文件。我的问题是如何修改inotifywait
仅当创建某种类型/扩展名的文件(或移动到目录中)时才报告的命令。例如,它应该报告何时.xml
创建任何文件。
我尝试过的:
我已运行该inotifywait --help
命令,并已阅读命令行选项。它有--exclude <pattern>
和--excludei <pattern>
选项排除某些类型的文件(通过使用正则表达式),但我需要一种方法包括只是某种类型/扩展名的文件。
答案1
如何修改
inotifywait
命令以仅在创建特定类型/扩展名的文件时报告
请注意,这是未经测试的代码inotify
因为我现在无法访问。但与此类似的东西应该适用于bash
:
inotifywait -m /path -e create -e moved_to |
while read -r directory action file; do
if [[ "$file" =~ .*xml$ ]]; then # Does the file end with .xml?
echo "xml file" # If so, do your thing here!
fi
done
或者,没有bash
,
inotifywait -m /path -e create -e moved_to |
while read -r directory action file; do
case "$file" in
(*.xml)
echo "xml file" # Do your thing here!
;;
esac
fi
done
使用较新版本的inotifywait
您可以直接为文件创建模式匹配:
inotifywait -m /path -e create -e moved_to --include '.*\.xml$' |
while read -r directory action file; do
echo "xml file" # Do your thing here!
done
答案2
--include
和--includei
是实际选项,至少在二进制文件的主版本中:
答案3
虽然双重否定方法之前的答案是一个好主意,因为(正如 TMG 指出的)它确实将过滤工作转移到inotifywait
,但这是不正确的。
例如,如果文件以 结尾,as
则它将不匹配,[^j][^s]$
因为最后一个字母s
不匹配[^s]
,因此不会将其排除。
用布尔术语来说,ifS
是这样的语句:
“最后一个字母是
s
”
并且J
是这样的声明:
“倒数第二个字母是
j
”
那么参数的值--exclude
在语义上应该等于not(J and S)
,即德摩根定律是not(J) or not(S)
。
另一个潜在的问题是zsh
, in$path
是一个内置变量,表示与 等价的数组$PATH
,因此该while read path ...
行将完全混乱$PATH
并导致所有内容都无法从 shell 执行。
因此正确的做法是:
inotifywait -m --exclude "[^j].$|[^s]$" /path -e create -e moved_to |
while read dir action file; do
echo "The file '$file' appeared in directory '$dir' via '$action'"
done
请注意.
after 需要[^j]
确保匹配应用于倒数第二个位置,并且字符|
(表示上面提到的布尔 OR)不应在此处转义,因为--exclude
采用 POSIX 扩展正则表达式。
不过,请参阅并投票@埃里科廷的回答对于较新版本来说,这inotifywait
是一种更简洁的方法。
答案4
使用双重否定:
inotifywait -m --exclude "[^j][^s]$" /path -e create -e moved_to |
while read path action file; do
echo "The file '$file' appeared in directory '$path' via '$action'"
done
这将只包含 javascript 文件