检测到文件夹中正在复制文件
Detecting that files are being copied in a folder
我正在 运行ning 一个脚本,如果一个文件夹不存在(或不一致),它会从特定位置复制一个文件夹。当我 运行 同时执行脚本 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
复制的任何想法?
As the first script is trying to copy the files, the second comes and
tries the same thing resulting in a mess
最简单的方法是创建一个文件,如果另一个脚本实例是 运行,该文件将包含 1。然后你可以根据那个添加条件。
{local $/; open my $fh, "<", 'flag' or die $!; $data = <$fh>};
die "another instance of script is running" if $data == 1;
另一种方法是在脚本中设置环境变量并在 BEGIN
块中检查它。
如果您需要系统范围的互斥锁,那么 "trick" 就是(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
。
这也是这种方法的缺点:如果您的复制代码崩溃并且脚本过早终止,那么该目录不会被删除。据推测, 中建议的锁定文件机制在这种情况下表现更好,并自动解锁文件。
听起来像是 lock file 的工作。有无数的 CPAN 模块实现了锁定文件,但其中大多数在 Windows 上不起作用。根据 CPAN 测试人员的说法,这里有一些似乎支持 Windows:
快速查看源代码后,我唯一可以推荐的模块是File::Flock::Tiny。其他人看起来很活泼。
你可以使用 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...
}
我正在 运行ning 一个脚本,如果一个文件夹不存在(或不一致),它会从特定位置复制一个文件夹。当我 运行 同时执行脚本 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
复制的任何想法?
As the first script is trying to copy the files, the second comes and tries the same thing resulting in a mess
最简单的方法是创建一个文件,如果另一个脚本实例是 运行,该文件将包含 1。然后你可以根据那个添加条件。
{local $/; open my $fh, "<", 'flag' or die $!; $data = <$fh>};
die "another instance of script is running" if $data == 1;
另一种方法是在脚本中设置环境变量并在 BEGIN
块中检查它。
如果您需要系统范围的互斥锁,那么 "trick" 就是(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
。
这也是这种方法的缺点:如果您的复制代码崩溃并且脚本过早终止,那么该目录不会被删除。据推测,
听起来像是 lock file 的工作。有无数的 CPAN 模块实现了锁定文件,但其中大多数在 Windows 上不起作用。根据 CPAN 测试人员的说法,这里有一些似乎支持 Windows:
快速查看源代码后,我唯一可以推荐的模块是File::Flock::Tiny。其他人看起来很活泼。
你可以使用 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...
}