简体   繁体   English

检测正在将文件复制到文件夹中

[英]Detecting that files are being copied in a folder

I am running a script which copies one folder from a specific location if it does not exist( or is not consistent). 我正在运行一个脚本,如果它不存在(或不一致),则从特定位置复制一个文件夹。 The problems appears when I run concurently the script 2+ times. 当我多次运行脚本2次以上时会出现问题。 As the first script is trying to copy the files, the second comes and tryes the same thing resulting in a mess. 当第一个脚本试图复制文件时,第二个脚本会尝试同样的事情导致一团糟。 How could I avoid this situation? 我怎么能避免这种情况? Something like system wide mutex. 类似于系统范围的互斥体。

I tryed a simple test with -w , I manually copied the folder and while the folder was copying I run the script: 我用-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";
}

Of course this won't work, cuz I still have write acces to that folder. 当然这不起作用,因为我仍然有写入该文件夹的访问权限。 Any ideea of how could I check if the folder is being copied in Perl or using batch commands ? 任何想法如何检查文件夹是否在Perl中复制或使用batch commands

Sounds like a job for a lock file . 听起来像锁文件的工作 There are myriads of CPAN modules that implement lock files, but most of them don't work on Windows. 有无数的CPAN模块可以实现锁定文件,但大多数都不能在Windows上运行。 Here are a few that seem to support Windows according to CPAN Testers: 根据CPAN测试人员,以下是一些似乎支持Windows的方法:

After having a quick view at the source code, the only module I can recommend is File::Flock::Tiny . 在快速查看源代码后,我可以推荐的唯一模块是File :: Flock :: Tiny The others seem racy. 其他人似乎很生气。

If you need a systemwide mutex, then one "trick" is to (ab)use a directory. 如果你需要一个系统范围的互斥锁,那么一个“技巧”是(ab)使用一个目录。 The command mkdir is usually atomic and either works or doesn't (if the directory already exists). 命令mkdir通常是原子的,可以工作也可以不工作(如果目录已经存在)。

Change your script as follows: 更改脚本如下:

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";
}

The only thing you need to make sure is that you're allowed to create a directory in /tmp (or wherever). 您唯一需要确保的是,您可以在/tmp (或其中)创建目录。

Note that I intentionally do NOT firstly test for the existence of $mutex_dir because between the if (not -d $mutex_dir) and the mkdir someone else could create the directory and the mkdir would fail anyway. 请注意,我故意首先测试$mutex_dir的存在,因为在if (not -d $mutex_dir)mkdir其他人可以创建目录,而mkdir无论如何都会失败。 So simply call mkdir . 所以简单地调用mkdir If it worked then you can do your stuff. 如果它工作,那么你可以做你的东西。 Don't forget to remove the $mutex_dir after you're done. 完成后不要忘记删除$mutex_dir

That's also the downside of this approach: If your copy-code crashes and the script prematurely dies then the directory isn't deleted. 这也是这种方法的缺点:如果您的复制代码崩溃并且脚本过早死亡,那么该目录不会被删除。 Presumably the lock file mechanism suggested in nwellnhof's answer behaves better in that case and automatically unlocks the file. 据推测,在nwellnhof的答案中建议的锁定文件机制在这种情况下表现得更好,并自动解锁文件。

As the first script is trying to copy the files, the second comes and tries the same thing resulting in a mess 当第一个脚本试图复制文件时,第二个脚本会尝试同样的事情导致一团糟

A simplest approach would be to create a file which will contain 1 if another instance of script is running. 最简单的方法是创建一个文件,如果另一个脚本实例正在运行,该文件将包含1。 Then you can add a conditional based on that. 然后,您可以添加条件。

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

Another approach would be to set an environment variable within the script and check it in BEGIN block. 另一种方法是在脚本中设置环境变量并在BEGIN块中检查它。

You can use Windows-Mutex or Windows-Semaphore Objects of the package http://search.cpan.org/~cjm/Win32-IPC-1.11/ 您可以使用包http://search.cpan.org/~cjm/Win32-IPC-1.11/的 Windows-Mutex或Windows-Semaphore对象

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...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么从容器内部复制到已安装文件夹的文件没有出现在主机文件夹中? - Why are files copied to mounted folder from inside the container not appearing in the host folder? 如何从搜索中排除可能正在使用或在python中复制的文件? - How do I exclude files from a search that may be in use or being copied to in python? 在Windows命令中将两个文件合并为一个文件只会导致第一个文件被复制 - Combining two files into a single in windows command only result in the first file being copied 如何限制文件被移动到Win10中的另一个文件夹? - How to restrict files to being moved to another folder in win10? 等到所有文件都复制完? - Wait until all the files are copied? 检测移动文件事件 - Detecting moved files events Robocopy 显示百分比,但不显示正在复制的每个文件 - Robocopy to show percentages but not each file being copied 如何自动创建名称为当天的文件夹并将现有文件和子文件夹移动到该文件夹​​中? - How to automatically create folder with name being current day and move existing files and subfolders into that folder? 批量文件,用于解锁从Internet复制的文件 - Batch file to unblock files copied from internet 如果未复制任何文件,则在复制末尾产生错误 - Generate error at the end of the copy if any files are not copied
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM