用于监视文件更改和执行命令的Bash脚本
我有一个带有一堆子文件夹的文件夹,这些文件夹有asciidoctor
格式化.adoc
扩展名。
每次我对文件进行更改(通常是这样)我都需要运行
asciidoctor -q filename.adoc
将其编译成HTML格式。
我正在尝试自动化这个过程。 到目前为止,我已经使用entr来了:
ls *.adoc | entr asciidoctor -q *.adoc
但仅适用于现有文件夹而不适用于子文件夹。 我尝试过这种变化,但它不起作用:
find . -name '*.adoc' | entr asciidoctor -q *.adoc
有关如何为所有子文件夹实现此自动化过程的任何想法?
Linux提供了一个很好的界面来监视所有文件系统事件,如创建,修改,删除文件。 该接口是inotify
系统调用系列,利用这些调用的用户空间实用程序由Ubuntu中的inotify-tools
包提供(可在Universe存储库中获得)。 如果您还没有,请按以下方式安装:
sudo apt-get install inotify-tools
inotify-tools
提供了inotifywait
和inotifywatch
二进制文件,我们需要第一个。
所以你想在修改任何.adoc
文件时运行命令asciidoctor -q some_file
( some_file
将替换为),如果这样,假设你的.adoc
文件在目录/foo/bar
,你可以设置watch:
inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc
-
-q
启用安静模式,inotifywait
本身没有信息 -
-m
启用监控模式,否则它将在第一个事件后退出 -
--event modify
,我们只对modify
事件感兴趣,即modify
文件时。 其他可能的值包括open
,close
等。 -
--format %w
,我们只想要修改的文件名而不是一堆其他信息,因为我们将使用文件名作为另一个命令的输入 -
/foo/bar/*.adoc
将扩展到/foo/bar
目录下的所有.adoc
文件
现在上面将显示修改后的文件名,现在在文件名上运行命令(假设命令通过STDIN获取参数):
inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc | asciidoctor -q
您还可以在目录上设置递归监视,然后您将需要使用grep
仅过滤所需的文件。 这里以递归方式( -r
)在目录/foo/bar
上设置监视并使用grep
仅过滤.adoc
文件:
inotifywait -qrm --event modify --format '%w%f' /foo/bar | grep '\.adoc$' | asciidoctor -q
当观察目录时,输出格式说明符%w
解析为目录名,因此我们需要%f
来获取文件名。 在观看文件时, %f
将解析为空字符串。
请注意,您还可以在守护进程( -d
)模式下运行inotifywait
,您也可以编写整个脚本,和/或在后台运行,和/或使用更多其他选项。
此外,如果需要,您可以使用您选择的任何其他命令替换asciidoctor
。
检查man inotifywait
以获得更多想法。
使用inotifywait
是一种典型的方法,但是还有一个名为inotify-hookable
inotifywait
的独立实用程序,它允许您在文件(或目录)更改时运行命令:
inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'
它似乎在触发命令一次后退出; 我没有看到连续观看的选项,所以你可以这样做:
while true; do inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc' echo "== $(date) : executed, continuing to monitor..." done
请注意,可以选择以递归方式监视多个文件或目录,以及忽略文件/路径的选项。
好吧,我推荐以下内容。
#!/bin/bash #Script for SRC in *.adoc; do asciidoctor -q $SRC done