Linux 基于Bash的热重载实现
tl;dr版本 问题:如何使bash脚本/命令侦听对文件的更改,然后输出特定bash命令的结果 长版本 真实场景:我正在重构一个Perl模块(my_module.pm),我有一个与该模块(my_module.t)关联的测试文件。我想将控制台放在一个屏幕上,每当我保存pm文件时(使用另一个屏幕上的编辑器),控制台就会运行Linux 基于Bash的热重载实现,linux,bash,unit-testing,automated-tests,git-bash,Linux,Bash,Unit Testing,Automated Tests,Git Bash,tl;dr版本 问题:如何使bash脚本/命令侦听对文件的更改,然后输出特定bash命令的结果 长版本 真实场景:我正在重构一个Perl模块(my_module.pm),我有一个与该模块(my_module.t)关联的测试文件。我想将控制台放在一个屏幕上,每当我保存pm文件时(使用另一个屏幕上的编辑器),控制台就会运行prove-v my_module.t 背景:我拥有当前目录中的所有权限,如果需要,我可以提升到sudo。我不介意实现是否类似于setInterval,因为它仅用于开发目的。只要我
prove-v my_module.t
背景:我拥有当前目录中的所有权限,如果需要,我可以提升到sudo
。我不介意实现是否类似于setInterval
,因为它仅用于开发目的。只要我有办法clearInterval
并且当文件没有更改时脚本不会产生永无止境的输出,那就好了:)
示例场景:
假设bash脚本名为hot
,只要给定的文件发生更改,它就会运行ls-lsource.txt
。
因此,当我运行hot source.txt
时,脚本可能会或不会运行ls….
一次。然后当我修改source.txt
时,运行hot
的控制台将再次运行ls
,我将看到source.txt
的新文件大小(以及其他信息)。
如果我运行hot something.txt
,当修改source.txt
时,它不应该运行ls
。即使未修改source.txt
,只要我修改something.txt
,脚本也会触发ls
我想这在while
循环中是可能的,但我在跟踪文件更改时有困难(最好是以较少资源占用的间隔进行跟踪)。任何帮助都将不胜感激 用于监视文件的更改事件,并对其修改运行测试
inotifywait -q -m -e close_write my_module.pm |
while read -r filename event; do
prove -v my_module.t
done
这些标志的用法如下所示。您案例中的事件-e
标志为close\u write
,这意味着文件在最近打开进行写入后已关闭
-q, --quiet
If specified once, the program will be less verbose. Specifically, it will not state when
it has completed establishing all inotify watches. If specified twice, the
program will output nothing at all, except in the case of fatal errors.
-m, --monitor
Instead of exiting after receiving a single event, execute indefinitely. The default
behaviour is to exit after the first event occurs.
-e <event>, --event <event>
Listen for specific event(s) only.
close_write
A watched file or a file within a watched directory was closed, after being opened in
writeable mode. This does not necessarily imply the file was written to.
-q,--quiet
如果指定一次,程序将不会太冗长。具体来说,它不会说明什么时候
它已经完成了所有inotify手表的建立。如果指定两次,则
程序将不输出任何内容,除非出现致命错误。
-m、 --监视器
不要在收到单个事件后退出,而是无限期执行。默认值
行为是在第一个事件发生后退出。
-事件
仅收听特定事件。
合写
在中打开监视的文件或监视目录中的文件后,该文件被关闭
可写模式。这并不一定意味着该文件已写入。
我最终向我的~/.bashrc
提出了这个函数:
function hot {
if (( $# < 2 )); then
echo 'USAGE: hot <command> <file1> [<file2> ... <fileN>]'
echo '<command> will be run once when any of the files listed is changed (i.e. ls -l <file> has its output changed)'
else
script=$1
shift
a='';
while true; do
b=`ls -l $*`
[[ $a != $b ]] && a=$b && eval $script;
sleep .5;
done
fi
}
功能热{
如果($#<2));那么
echo“用法:热[…]”
echo“当列出的任何文件发生更改时(即ls-l的输出发生更改),将运行一次”
其他的
脚本=$1
转移
a=“”;
虽然是真的;做
b=`ls-l$*`
[[$a!=$b]]&&a=$b&&eval$script;
睡眠;
完成
fi
}
因此,我可以做hot'证明我的_module.t'我的_module.pm
,正如示例中所述,我还可以做hot'ls-l source.txt'source.txt
实际上,我希望在文件或测试文件更改后运行测试。因此,我会做hot'证明我的模块.t'我的模块.pm我的模块.t
行[[$a!=$b]]&&a=$b&&eval$script
是为了避免将自己与嵌套if混淆——这是一种做a=$b的“简短形式”;如果$a!=$b
希望这能帮助其他人寻找答案。:) 您有权访问inotify
?我想是的-我现在没有访问虚拟机的权限,但它是在CentOS上构建的,所以我想是的…您能使用哪个inotifywait
快速确认它吗?看看它是否存在。它非常简单地使用它,或者像在中那样下载inotifywait
:/usr/bin/which:no inotifywait in(…)中一样,并且在我尝试运行which inotify
时也会得到相同的结果。。。我有sudo
访问权限,可以为它运行yum安装
,如果这有助于解决热重新加载问题:)Mm。。我的盒子失去了传出连接,因此我正在将.tar.gz
传输到机器上,但是我对autoreconf
和automake
不太熟悉(不确定命令行选项)。哪些命令可以帮助我安装inotify tools
?@SunnyPun:只需执行/configure--prefix=/usr&&make&&su-c'make install'
,如页面中所述,在提取归档文件后在文件夹中执行此操作。。。我在运行inotifywait
时遇到此错误:inotifywait:加载共享库时出错:libinotifytools.so.0:无法打开共享对象文件:没有此类文件或目录
。除了ldconfig:/usr/lib/libinotifytools之外,安装似乎进行得很顺利。因此.0不是一个符号链接
@SunnyPun:将另一个选项添加到/configure
作为/configure--prefix=/usr--libdir=/lib64&&make&&su-c'make install'
感谢您的耐心等待。。现在我正在运行这个inotifywait-q-m-e close_write gg.txt>while read-r filename事件;do>ls>done
和dovi gg.txt
在另一个bash的同一文件夹中(并使用:x
保存文件)。这没有给我任何输出。。。我该怎么办?