检测文件是否正在文件夹

时间:2016-10-13 12:33:58

标签: windows perl batch-file lockfile

我正在运行一个脚本,如果它不存在(或不一致),则从特定位置复制一个文件夹。当我多次运行脚本2次以上时会出现问题。当第一个脚本试图复制文件时,第二个脚本会尝试同样的事情导致一团糟。我怎么能避免这种情况?类似于系统范围的互斥体。

我用-w尝试了一个简单的测试,我手动复制了文件夹,当文件夹复制时我运行脚本:

use strict;
use warnings;

my $filename = 'd:\\folder_to_copy';
if (-w $filename) {
  print "i can write to the file\n";
} else {
  print "yikes, i can't write to the file!\n";
}

当然这不起作用,因为我仍然有写该文件夹的访问权限。 有关如何检查文件夹是否在Perl或使用batch commands进行复制的任何想法?

4 个答案:

答案 0 :(得分:7)

听起来像lock file的工作。有无数的CPAN模块可以实现锁定文件,但大多数都不能在Windows上运行。根据CPAN测试人员的说法,这里有一些似乎支持Windows:

在对源代码进行快速查看之后,我可以推荐的唯一模块是 File :: Flock :: Tiny 。其他人看起来很活泼。

答案 1 :(得分:4)

如果您需要系统范围的互斥锁,那么就需要一个"技巧"是(ab)使用目录。命令mkdir通常是原子的,无论是有效还是无效(如果目录已经存在)。

按如下方式更改脚本:

my $mutex_dir = '/tmp/my-mutex-dir';
if ( mkdir $mutex_dir ) {

    # run your copy-code here

    # when finished:
    rmdir $mutex_dir;
} else {
    print "another instance is already running.\n";
}

您唯一需要确保的是,您可以在/tmp(或任何地方)创建目录。

请注意,我有意识地 NOT 首先测试$mutex_dir是否存在,因为在if (not -d $mutex_dir)mkdir之间,其他人可以创建目录和mkdir无论如何都会失败。所以只需致电mkdir。如果它工作,那么你可以做你的东西。在您完成后忘记删除$mutex_dir

这也是这种方法的缺点:如果你的拷贝代码崩溃并且脚本过早死亡,那么目录就不会被删除。据推测,nwellnhof's answer中建议的锁定文件机制在这种情况下表现更好,并自动解锁文件。

答案 2 :(得分:3)

  

当第一个脚本试图复制文件时,第二个脚本来了    尝试同样的事情导致一团糟

最简单的方法是创建一个文件,如果另一个脚本实例正在运行,该文件将包含1。然后你可以根据它添加一个条件。

{local $/; open my $fh, "<", 'flag' or die $!; $data = <$fh>};
die "another instance of script is running" if $data == 1;

另一种方法是在脚本中设置环境变量,并在BEGIN块中进行检查。

答案 3 :(得分:1)

您可以使用该软件包的Windows-Mutex或Windows-Semaphore对象 http://search.cpan.org/~cjm/Win32-IPC-1.11/

use Win32::Mutex;
use Digest::MD5 qw (md5_hex);
my $mutex = Win32::Mutex->new(0, md5_hex $filename);
if ($mutex) {
     do_your_job();
     $mutex->release
} else {
     #fail...
}