Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 基于Bash的热重载实现_Linux_Bash_Unit Testing_Automated Tests_Git Bash - Fatal编程技术网

Linux 基于Bash的热重载实现

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,因为它仅用于开发目的。只要我

tl;dr版本 问题:如何使bash脚本/命令侦听对文件的更改,然后输出特定bash命令的结果

长版本 真实场景:我正在重构一个Perl模块(my_module.pm),我有一个与该模块(my_module.t)关联的测试文件。我想将控制台放在一个屏幕上,每当我保存pm文件时(使用另一个屏幕上的编辑器),控制台就会运行
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
和do
vi gg.txt
在另一个bash的同一文件夹中(并使用
:x
保存文件)。这没有给我任何输出。。。我该怎么办?