用于监视文件更改和执行命令的 Bash 脚本

bra*_*ran 17 filesystem command-line bash

我有一个包含一堆子文件夹的文件夹,这些文件夹已asciidoctor格式化为带有.adoc扩展名的文件。

每次我对文件进行更改时(通常是这样),我都需要运行

asciidoctor -q filename.adoc
Run Code Online (Sandbox Code Playgroud)

将其编译为 HTML 格式。

我正在尝试自动化该过程。到目前为止,我已经使用了entr:

ls *.adoc | entr asciidoctor -q *.adoc
Run Code Online (Sandbox Code Playgroud)

但仅适用于现有文件夹,不适用于子文件夹。我已经尝试过这种变体,但它不起作用:

find . -name '*.adoc' | entr asciidoctor -q *.adoc
Run Code Online (Sandbox Code Playgroud)

有什么想法可以为所有子文件夹实现这个自动化过程吗?

hee*_*ayl 24

Linux 提供了一个很好的界面来监控所有文件系统事件,比如创建、修改、删除文件。该接口是inotify系统调用系列,利用这些调用的用户空间实用程序由inotify-toolsUbuntu 中的软件包提供(可在 Universe 存储库中获得)。如果您还没有,请通过以下方式安装:

sudo apt-get install inotify-tools
Run Code Online (Sandbox Code Playgroud)

inotify-tools提供inotifywait和inotifywatch二进制文件,我们需要第一个。


因此,您希望在修改asciidoctor -q some_file任何.adoc文件时运行该命令(some_file将被该文件替换),如果假设您的.adoc文件在目录中/foo/bar,则可以设置监视:

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc
Run Code Online (Sandbox Code Playgroud)
  • -q启用安静模式,没有来自inotifywait自身的信息

  • -m 开启监听模式,否则会在第一个事件后退出

  • --event modify,我们只对modify事件感兴趣,即文件被修改时。其他可能的值包括open,close等等。

  • --format %w,我们只想要修改的文件名而不是一堆其他信息,因为我们将使用文件名作为另一个命令的输入

  • /foo/bar/*.adoc将扩大到所有.adoc在文件/foo/bar目录


现在,无论何时修改任何文件,上面都会显示文件名,现在在文件名上运行命令(假设命令通过 STDIN 获取参数):

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc | asciidoctor -q
Run Code Online (Sandbox Code Playgroud)

您还可以在目录上设置递归监视,然后您只需要使用它grep来过滤所需的文件。这里以递归方式 ( -r) 在目录上设置监视/foo/bar并grep用于仅过滤.adoc文件:

inotifywait -qrm --event modify --format '%w%f' /foo/bar | grep '\.adoc$' | asciidoctor -q
Run Code Online (Sandbox Code Playgroud)

在查看目录时,输出格式说明符%w解析为目录名,因此我们需要%f获取文件名。在观看文件时,%f将解析为空字符串。

请注意,您还可以inotifywait在守护进程 ( -d) 模式下运行,也可以编写整个程序的脚本,和/或在后台运行,和/或使用更多其他选项。

此外,如果需要,您可以替换asciidoctor为您选择的任何其他命令。

检查man inotifywait以获得更多想法。


Sha*_*iri 6

有很多工具,特别是如果你搜索你的存储库

apt-cache search monitor | grep file
Run Code Online (Sandbox Code Playgroud)

这给了我们很多工具。但是您不必测试它们,因为我这样做了。

我已经测试了这些工具和许多其他工具:

  • 通知
  • fswatch
  • 文件监视
  • 色板
  • 文件已更改
  • 进入

在这些工具中,我发现其中三个有用且可靠:

  • 直接| 用 C 编写的 GNU
  • 手表| 在 Perl 中
  • 狙击手

而从这三者中,最直接的无疑是最好的。

它非常有用和可靠,我已经将它用于我拥有的微服务的简单管道。

direvent.conf 观看文件

syslog {
    facility local0;
    tag "direvent";
    print-priority yes;
}

watcher {
    path /var/www/html/ir/jsfun/build/react recursive;
    file "*.js";
    event write;
    command "/usr/bin/xdotool search --onlyvisible  --class firefox key F5";
    option (stdout, stderr, wait);
}
Run Code Online (Sandbox Code Playgroud)

这只是我拥有的配置文件之一,每当写入发生更改时,就会执行此命令 - 这也可能是一个脚本。

无需使用while循环或其他东西。


特征

  • 递归观察目录
  • 可以在前台或后台作为守护进程运行
  • 便携的。我在 Ubuntu 和 CentOS7 服务器中都有它
  • 文件名报告
  • 正则表达式支持文件匹配
  • 多文件观看(观看不止一种类型的文件)
  • 同步命令执行(如果我们有多个观察者)
  • syslog 处理(如果需要,记录到 syslog)
  • 易于使用且良好的 CLI 和配置文件设计

由谢尔盖波兹尼亚科夫开发。


安装

sudo apt install direvent
Run Code Online (Sandbox Code Playgroud)

但是使用其源代码安装它非常简单直接,它为您提供了最新版本(现在是:5.1)。


mic*_*ael 5

Usinginotifywait是典型的方法,但还有一个单独的实用程序inotify-hookable,它可以让您在文件(或目录)更改时运行命令:

inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'
Run Code Online (Sandbox Code Playgroud)

好像是触发一次命令就退出了;我没有看到连续观看的选项,因此您可以执行以下操作:

while true; do
    inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'
    echo "== $(date) : executed, continuing to monitor..."
done
Run Code Online (Sandbox Code Playgroud)

请注意,有一些选项可以递归地监视多个文件或目录,也可以选择忽略文件/路径。

  • 为我运行命令后,inotify-hookable 不会退出。唔 (3认同)