监视一组文件中的更改,并在更改时对其执行命令 [英] Monitor a set of files for changes and execute a command on them when they do

查看:93
本文介绍了监视一组文件中的更改,并在更改时对其执行命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想到的(命令行)界面如下:

The (command line) interface I have in mind is like so:

watching FILE+ do COMMAND [ARGS] (and COMMAND [ARGS])*

任何出现 {}的地方 COMMAND 中的code>将替换为已更改文件的名称。请注意, do 是关键字。

Where any occurrence of "{}" in COMMAND is replaced with the name of the file that changed. And note that "do" and "and" are keywords.

例如:

> watching foo.txt bar.txt do scp {} somewhere.com:. and echo moved {} to somewhere

或:

> watching foo.c do gcc foo.c and ./a.out

我不愿意该接口。我将添加执行此操作的脚本作为答案,看看是否有人有更好的方法或改进它的方法。

I'm not wedded to that interface though. I'll add my script that does that as an answer and see if anyone has anything better or ways to improve it.

推荐答案

#!/usr/bin/perl
# Run some commands whenever any of a set of files changes (see USAGE below).
# Example:
# ./watching.pl foo.txt bar.txt do scp foo.txt remote.com:. and cat bar.txt
# To only do something to the file that changed, refer to it as {}.

$| = 1;  # autoflush

my $p = position("do", @ARGV); # position of 1st occurrence of "do" in @ARGV.
if (@ARGV < 3 || $p == -1 || !($p >= 1 && $p < $#ARGV)) {
  die "USAGE: watching FILE+ do COMMAND [ARGS] (and COMMAND [ARGS])*\n";
}

my $cmdstr = join(' ', splice(@ARGV, $p+1));  # grab stuff after the "do"
my @cmds = split(/\s+and\s+/, $cmdstr);
pop(@ARGV);  # remove the "do" on the end.
my @targets = @ARGV;
print "Watching {", join(' ', @targets), "} do (", join('; ', @cmds), "):\n";

# initialize the %last hash for last mod time of each file.
for my $t (@targets) {
  ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
   $atime,$mtime,$ctime,$blksize,$blocks) = stat($t);
  $last{$t} = $mtime;
}

my $i = 1;
while(1) {
  if($i % (45*60) == 0) { print "."; }

  for my $t (@targets) {
    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
     $atime,$mtime,$ctime,$blksize,$blocks) = stat($t);

    if ($mtime != $last{$t}) {
      print "\nCHANGE DETECTED TO $t\n";
      for (@cmds) { my $tmp = $_; $tmp =~ s/\{\}/$t/g; system($tmp); }
      $last{$t} = $mtime;
    }
  }
  sleep(1);
  $i++;
}


# Call like so: position($element, @list).
sub position {
  my $x = shift;
  if(@_==0) { return -1; }
  if($x eq $_[0]) { return 0; }
  shift;
  my $p = position($x,@_);
  if($p==-1) { return -1; }
  return 1+$p;
}

这篇关于监视一组文件中的更改,并在更改时对其执行命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆