我有一个文件夹,里面有我用inotifywait
(来自inotify-tools)观看的Sphinx文档。该脚本重新构建html&singlehtml并刷新Chrome。
#!/bin/sh
inotifywait -mr source --exclude _build -e close_write -e create -e delete -e move | while read file event; do
make html singlehtml
xdotool search --name Chromium key --window %@ F5
done
保存单个文件时,此工作正常。但是,当我hg update
旧版本或粘贴source
文件夹中的多个文件时,它会为每个文件触发脚本。
是否有一个简单的解决方法(没有编写自定义python脚本 - 我可以这样做)让它在启动脚本之前等待几分之一秒?
我制作了一个更复杂的shell脚本并将其发布在the article中:
inotifywait -mr source --exclude _build -e close_write -e create -e delete -e move --format '%w %e %T' --timefmt '%H%M%S' | while read file event tm; do
current=$(date +'%H%M%S')
delta=`expr $current - $tm`
if [ $delta -lt 2 -a $delta -gt -2 ] ; then
sleep 1 # sleep 1 set to let file operations end
make html singlehtml
xdotool search --name Chromium key --window %@ F5
fi
done
它使inotifywait不仅记录文件名和操作,还记录时间戳。该脚本将时间戳与当前的unixtime进行比较,如果delta小于2秒,则运行make html
。但在此之前它会睡1秒钟让文件操作系统结束。对于下一个修改过的文件,时间戳将是旧的,增量将超过2秒,并且不会执行任何操作。
我发现这种方式消耗的CPU最少且最可靠。
我也试过运行一个简单的Python脚本,但这意味着如果我将一些像jQueryUI一样大的东西粘贴到文件夹中,就会产生一千个进程然后变成僵尸。
试试这个:
last_update=0
inotifywait -mr source --exclude _build -e close_write -e create \
-e delete -e move --format '%T' --timefmt '%s' |
while read timestamp; do
if test $timestamp -ge $last_update; then
sleep 1
last_update=$(date +%s)
make html singlehtml
xdotool search --name Chromium key --window %@ F5
fi
done
--format '%T' --timefmt '%s'
导致为每个事件输出时间戳。test $timestamp -ge $last_update
将事件时间戳与上次更新的时间戳进行比较。因此跳过在睡眠期间发生的任何事件。sleep 1
以等待事件累积。较短的持续时间可能在这里很好,例如sleep 0.5
,但它的便携性会降低。last_update=$(date +%s%N)
设置上次更新的时间戳,以与下一个事件的时间戳进行比较。以这种方式,在循环的下一次迭代期间丢弃在sleep 1
期间发生的任何其他事件。注意,这里存在竞争条件,因为strftime()不支持纳秒。如果一组事件穿过第二个边界,此示例可以运行make
两次。要冒险丢失事件,请将-ge
替换为-gt
。