我正在使用psexec在远程Windows机器上启动Perl程序。该程序对xcopy进行系统调用。这在机器上直接(本地)运行时工作正常,但是当通过psexec远程运行时,xcopy失败并显示以下消息:
文件创建错误 - 功能不正确。
(取决于用户,该消息可能改为“拒绝访问”。)
注意$!给出以下诊断:
syscall.pl中的错误文件描述符。 perl在REMOTE上退出,错误代码为9。
通过system()或反引号调用xcopy似乎没什么区别。
我应该指出“from”文件夹是一个ClearCase动态视图(M盘)。
奇怪的是,直接从psexec调用时,xcopy似乎正常工作。
以下是其他一些奇怪之处:</ p>
xcopy并不总是失败。某些文件似乎只是“被诅咒”。只读属性似乎不是一个因素。
一旦复制成功(例如,通过Windows资源管理器),解除了诅咒,该特定文件将不再导致xcopy错误。
问题似乎与目标文件夹无关。解除诅咒后,可以将文件xcopy到新目的地。
以下是我用来缩小问题的测试Perl脚本的一部分(文件夹名称已被通用化)。 请注意,对于每个测试的“my $ cmd”,我都会注释掉前一个,并添加了状态注释。
# ClearCase directory M:\STUFF\ABC contains ABC.tst, ABC.zip and several nonempty subfolders
# Directory copy, D drive to D drive
#my $cmd = "xcopy D:\\temp\\src D:\\temp\\dest /e /i /y";
# works
# Directory copy, M drive to D drive
#my $cmd = "xcopy M:\\STUFF\\ABC D:\\temp\\dest /e /i /k /y";
# fails with "File creation error - Incorrect function" or "Access denied"
# File copy (.tst), M drive to D drive (trailing backslash)
#my $cmd = "xcopy M:\\STUFF\\ABC\\ABC.tst D:\\temp\\dest\\";
# works!
# Directory copy, M drive to D drive (trailing backslash)
#my $cmd = "xcopy M:\\STUFF\\ABC D:\\temp\\dest\\ /e /i /k /y";
# copies the .tst file, but fails on the .zip (yes, the .tst file is now getting copied)
# Directory copy, M drive to D drive (same as above but without trailing backslash)
#my $cmd = "xcopy M:\\STUFF\\ABC D:\\temp\\dest /e /i /k /y";
# copies the .tst file, but fails on the .zip
# File copy (.zip), M drive to D drive
#my $cmd = "xcopy M:\\STUFF\\ABC\\ABC.zip D:\\temp\\dest";
# fails
# File copy (.zip), M drive to D drive (trailing backslash)
#my $cmd = "xcopy M:\\STUFF\\ABC\\ABC.zip D:\\temp\\dest\\";
# fails
# After manually (Windows Explorer) copying the .zip file to the dest folder and deleting it
# Directory copy, M drive to D drive with /c (continue after failure)
#my $cmd = "xcopy M:\\STUFF\\ABC D:\\temp\\dest /c /i /e";
# copies the .tst and .zip file (!), but fails on all other files (folders were successfully created)
# After manually copying the Folder1 folder to the dest folder and then deleting it
#my $cmd = "xcopy M:\\STUFF\\ABC D:\\temp\\dest /c /i /e";
# copies the .tst and .zip file and the contents of Folder1(!), but fails on all other files
# Different dest:
my $cmd = "xcopy M:\\STUFF\\ABC D:\\temp\\dest1 /c /i /e";
# Same results as immediately above
print "Executing system command: $cmd ...\n";
system ($cmd);
#print(`$cmd 2>&1`); #same
答案 0 :(得分:3)
我建议您不要使用xcopy
命令,而是使用Perl本身进行复制。有一个模块File::Copy::Recursive,使用起来非常简单。它不是标准Perl发行版的一部分,因此您必须使用cpan
安装它。
如果您不想使用非本机模块,可以尝试使用File::Find查找目录中的文件,然后将其与File::Copy结合使用。
在Perl Monks上找到了两个例子。一个使用组合,另一个使用File::Copy::Recursive
是的,这不是直接回答您的问题,但您应尽量避免使用system
命令。当您与系统 shell 和命令处理器进行交互时(特别是当ClearCase与文件系统混乱时),您最终可能会遇到许多无意的交互,这些交互可能会导致某些情况下的某些工作,但不会其他
要找出您在system
调用时遇到的问题,您必须假设错误可能在ClearCase,cmd.exe
shell,xcopy
命令中,或者Perl。通过不使用system
命令,您已经简化了问题,并且很多时候实际上加快了这个过程。
答案 1 :(得分:3)
尝试从空设备重定向INPUT以查看xcopy是否有效。我不知道为什么,我很久以前遇到过这个问题,不知何故(可能通过网络搜索)想出来了。
它看起来像这样:
xcopy /args $source $target <nul:
;
(围绕整个命令反击不显示)
JKE
答案 2 :(得分:1)
File::Copy::Recursive可能会解决您的问题。
通过这种方式,您可以更加轻松地复制文件。您可以将此调用包装到eval块并在那里应用某种重试逻辑吗?
有问题的文件上的“虚拟更新”可能有帮助吗?更改文件的属性/时间戳或将其重命名为其他内容并重命名为...
答案 3 :(得分:1)
您是否尝试过使用参数列表system
?
my @args= qw(M:\STUFF\ABC D:\temp\dest1 /c /i /e);
warn "Executing 'xcopy @args' ...\n";
system xcopy => @args;
答案 4 :(得分:1)
如果你看how ClearCase manages read/write access for Vob and views,你会发现:
之间存在差异r-x
)--x
”+“r--
”因此,根据启动xcopy的流程背后的用户,您可能无法读取/访问某些目录/文件。
并且您需要确保使用已将CLEARCASE_PRIMARY_GROUP
设置为正确的值(即,作为vob的主要组或其次要组之一列出的组),以便访问Vob(但如果是保护是松散的,无论如何每个人都可以访问它。)
所有这些都适用于动态视图,并且仅适用于快照视图的更新(更新完成后,您可以在本地复制文件,任何进程都可以读取这些文件)。