我正在使用inotifywait
在文件系统事件发生时运行命令。我希望这等待5秒,看看是否发生了另一个文件系统事件,如果另一个文件系统事件发生了,我想将计时器重置为五秒钟并等待一些。有意义吗?
我的问题是我在Bash中攻击这个,我不知道我会怎么做。在JavaScript中,我将使用setTimeout和一些代码:
function doSomething() { ... }
var timer;
function setTimer() {
window.clearTimeout(timer)
timer = window.setTimeout(doSomething, 5000);
}
// and then I'd just plug setTimer into the inotifywait loop.
但Bash中是否有可寻址的,可清除的背景定时器?
答案 0 :(得分:0)
我已经喋喋不休的一个想法是分出一个睡眠的子shell,然后运行我想要的结束命令,然后将其填充到后台。如果它再次运行,它将获取之前的PID并尝试将其核对。
作为安全功能,在睡眠完成后,子shell清除$ PID以避免command
在执行中被杀死
PID=0
while inotifywait -r test/; do
[[ $PID -gt 0 ]] && kill -9 $PID
{ sleep 5; PID=0; command; } & PID=$!
done
它有点乱,但我已经测试了它并且它有效。如果我在./test/中创建新文件,它会看到并且如果$ PID不为零,它将终止先前的睡眠命令并重置计时器。
答案 1 :(得分:0)
我提供这个答案来说明一个类似但更复杂的用例。请注意,@ Oli提供的代码已包含在我的答案中。
我想对已更改的文件进行后期处理。具体来说,我想在scss
文件上调用dart-sass来生成css
文件及其映射文件。然后css
文件被压缩。
我的问题是,可以直接通过vim(写入文件时使用备份副本)或通过SFTP(特别是使用macOS Transmit)完成编辑/保存scss
源文件。这意味着可以将inotifywait
看作是一对CREATE
,然后是CLOSE_WRITE,CLOSE
或单个CREATE
(由于通过SFTP I的RENAME
cmd认为)。因此,如果看到CLOSE_WRITE,CLOSE
或CREATE
后面没有任何东西,我必须启动处理。
备注:
<filename>_safe_save_<digits>.scss
格式的临时文件不得考虑。inotify-tools
的版本是3.20.2.2,并且已从源代码编译(没有软件包管理器),以使用include
选项获得最新版本。#!/usr/bin/bash
declare -A pids
# $1: full path to source file (src_file_full)
# $2: full path to target file (dst_file_full)
function launch_dart() {
echo "dart"
/opt/dart-sass/sass "$1" "$2" && /usr/bin/gzip -9 -f -k "$2"
}
inotifywait -e close_write,create --include "\.scss$" -mr assets/css |
grep -v -P '(?:\w+)_safe_save_(?:\d+)\.scss$' --line-buffered |
while read dir action file; do
src_file_full="$dir$file"
dst_dir="${dir%assets/css/}"
dst_file="${file%.scss}.css"
dst_file_full="priv/static/css/${dst_dir%/}${dst_file}"
echo "'$action' on file '$file' in directory '$dir' ('$src_file_full')"
echo "dst_dir='$dst_dir', dst_file='$dst_file', dst_file_full='$dst_file_full'"
# if [ "$action" == "DELETE" ]; then
# rm -f "$dst_file_full" "${dst_file_full}.gz" "${dst_file_full}.map"
if [ "$action" == "CREATE" ]; then
echo "create. file size: " $(stat -c%s "$src_file_full")
{ sleep 1; pids[$src_file_full]=0; launch_dart "$src_file_full" "$dst_file_full"; } & pids[$src_file_full]=$!
elif [ "$action" == "CLOSE_WRITE,CLOSE" ]; then
[[ ${pids[$src_file_full]} -gt 0 ]] && kill -9 ${pids[$src_file_full]}
launch_dart "$src_file_full" "$dst_file_full"
fi
done