我正在使用psexec在远程Windows机器上启动Perl程序。 该程序会对xcopy进行系统调用。在机器上直接(本地)运行时,此工作正常,但通过psexec远程运行时,xcopy将失败,并显示以下消息:
文件创build错误 – function错误。
(取决于用户,消息可能会改为“访问被拒绝”。)
请注意$! 给出以下诊断:
syscall.pl中的文件描述符不正确。 perl在REMOTE上退出,错误代码为9。
是否通过system()或反引号调用xcopy似乎没有什么区别。
我应该指出,“from”文件夹是一个ClearCasedynamic视图(M盘)。
奇怪的是,从psexec直接调用xcopy似乎正常工作。
还有一些其他的怪事:
xcopy并不总是失败。 某些文件似乎被“诅咒”了。 只读属性似乎不是一个因素。
一旦复制成功(例如,通过Windows资源pipe理器),诅咒被取消,该特定文件将不再导致xcopy错误。
这个问题似乎与目标文件夹无关。 一旦诅咒被解除,文件可以被拷贝到一个新的目的地。
以下是我用来缩小问题的testingPerl脚本的一部分(文件夹名称已被泛化)。 请注意,对于每个testing过的“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
我建议不要使用xcopy
命令,而是使用Perl本身进行复制。 有一个File :: Copy :: Recursive模块,使用非常简单。 它不是标准的Perl发行版的一部分,所以你必须使用cpan
来安装它。
如果您不想使用非本地模块,则可以尝试使用File :: Find查找目录中的文件,然后将其与File :: Copy结合使用。
在Perl僧侣身上找到两个例子。 一个使用组合,另一个使用File::Copy::Recursive
是的,这不是直接回答你的问题,但你应该尽量避免使用system
命令。 当你与系统shell和命令处理器交互时(特别是当ClearCase使用文件系统的时候),你可能会遇到很多无意的交互,在某些情况下会导致某些东西能够工作,而不是其他的东西。
为了弄清楚system
调用的问题,你必须假定错误可能在ClearCase, cmd.exe
shell, xcopy
命令或者Perl中。 通过不使用system
命令,您已经简化了您的问题,并且多次实际上加快了这个过程。
尝试从空设备重定向INPUT,看看你的xcopy是否工作。 我不知道为什么,很久以前我遇到过这个问题,并且以某种方式(可能通过网络搜索)发现了这个问题。
它看起来像这样:
xcopy /args $source $target <nul:
(反攻整个命令没有出现)
JKE
你有没有尝试system
的参数列表?
my @args= qw(M:\STUFF\ABC D:\temp\dest1 /c /i /e); warn "Executing 'xcopy @args' ...\n"; system xcopy => @args;
File :: Copy :: Recursive可以解决你的问题。
这样你就有了一个更复杂的方式来复制文件。 你可以把这个调用包装到一个eval块中,并在那里应用某种重试逻辑?
也许一个“虚拟更新”有问题的文件的帮助? 更改文件的属性/时间戳或将其重命名为其他内容并将其重命名为…
如果你看看ClearCase如何管理Vob和视图的读/写访问 ,你会看到:
rx
) r--
”上只需要' --x
') 因此,根据启动xcopy的进程背后的用户,您可能无法读取/访问某些目录/文件。
而且你需要确保使用已经将CLEARCASE_PRIMARY_GROUP
设置为正确的值(即,被列为vob的主组或其次级组的一个组),以便访问Vob(但是如果其保护足够松弛,每个人都可以访问它)。
所有这些都适用于动态视图,并且仅适用于更新快照视图(一旦更新完成,您将文件复制到本地,并且可以被任何进程读取)。