如何使用inotifywait监视目录以创建特定扩展名的文件


21

我已经看到了这个答案

您应该考虑使用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>命令可以排除某些类型的文件(通过使用regEx),但是我需要一种方法来仅包括某些类型/扩展名的文件。


顺便说一句,path如果您想首先在shell中使用此名称,则使用上面的名称可能不是最佳的变量名称。如果使用它,则将无法使用命令和所有命令,因为这基本上已经覆盖了standard PATH。因此,我建议使用替代的var名称,例如fpath。也就是说,while read fpath action file通常从您的shell中可用的任何标准命令都将仍然存在。
Baptiste Mathus

没有包含选项是很荒谬的。
erandros

Answers:


17

如何修改inotifywait命令以仅在创建某些类型/扩展名的文件时报告

请注意,这是未经测试的代码,因为我目前无法访问inotify。但是与此类似的事情应该起作用:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        if [[ "$file" =~ .*xml$ ]]; then # Does the file end with .xml?
            echo "xml file" # If so, do your thing here!
        fi
    done

2
这确实有效,我已经用inotifywait对其进行了测试。
TheBetterJORT '17

1
你如何运行这个?它是一次性命令,还是需要循环运行或类似的东西?也许作为incron(但愿不是)的一部分。
SDsolar '17

@SDsolar有所不同。对于我来说,我通常运行inotify与任一nohup或自定义systemd服务启动它。多数情况下是后者。
maulinglawns

9

使用双重否定:

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文件


1
很好,我喜欢将过滤器转移到inotifywait而不是让所有文件生成巨大的输出并随后进行过滤(就像在其他答案中一样)。还没有尝试过,但是我想这样做的速度会更快一些。
TMG

这就是我想要的。如何修改--exclude输入以监视.ext文件。这只运行一次还是在for循环中?
kurokirasama

这是一个守护进程,因此它将一直运行直到崩溃或您将其关闭:)
Jonas Earendel

抱歉,错过了第一个问题。 inotifywait -m --exclude "[^.][^e][^x][^t]$" /home/jonas/Skrivbord/test -e create -e moved_to | while read path action file; do echo "The file '$file' appeared in directory '$path' via '$action'" done 我敢肯定正则表达式可以优化,但是这个婴儿可以用:)
Jonas Earendel

谢谢!我会尝试一下!!
kurokirasama

3

尽管先前答案的双重否定方法是一个不错的主意,因为(如TMG所指出的)确实确实将过滤工作移至inotifywait,这是不正确的。

例如,如果文件以结尾结尾,则该文件as将不匹配,[^j][^s]$因为最后一个字母s不匹配[^s],因此不会将其排除。

用布尔值表示,如果S是语句:

“最后一封信是s

J声明:

“倒数第二个字母是j

那么该--exclude参数的值在语义上应等于not(J and S),根据De Morgan的定律not(J) or not(S)

另一个潜在的问题是,中的zsh$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

请注意.,为[^j]确保在倒数第二个位置应用匹配项,之后需要这样做,并且|此处字符(表示上述布尔OR)不应转义,因为--exclude采用POSIX扩展正则表达式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.