Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Windows XCOPY fail when invoked via Perl system call via psexec?

I'm using psexec to launch a Perl program on remote Windows machines. The program makes a system call to xcopy.This works fine when run directly (locally) on the machines, but when run remotely via psexec, the xcopy fails with the following message:

File creation error - Incorrect function.

(Depending on the user, the message may instead be "Access denied.")

Note that $! gives the following diagnostic:

Bad file descriptor at syscall.pl. perl exited on REMOTE with error code 9.

It does not seem to make a difference whether xcopy is invoked via system() or backticks.

I should point out that the "from" folder is a ClearCase dynamic view (M drive).

Oddly enough, the xcopy seems to work correctly when called directly from psexec.

Here are some other oddities:

  1. The xcopy doesn't always fail. Certain files just seem to be "cursed". The read-only attribute appears not to be a factor.

  2. Once a copy succeeds (e.g., via Windows Explorer), the curse is lifted, and that particular file will no longer cause xcopy errors.

  3. The problem does not seem to be with the destination folder. Once the curse is lifted, the file can be xcopy'd to a new destination.

Following is a portion of the test Perl script I used to narrow down the problem (folder names have been genericized). Note that, for each "my $cmd" tested, I commented out the previous one, and added a status comment.

# 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
like image 508
UhClem Avatar asked Dec 27 '22 01:12

UhClem


1 Answers

I suggest that instead of using the xcopy command, you do the copying using Perl itself. There's a module File::Copy::Recursive that's pretty simple to use. It's not part of the standard Perl distribution, so you have to install it using cpan.

If you don't want to use non-native modules, you can try using File::Find to find the files in a directory, then combine that with File::Copy.

Found two examples on Perl Monks. One using the combination and the other using File::Copy::Recursive

Yes, this isn't answering your question directly, but you should try to avoid using system commands when possible. When you interact with the system shell and command processor (especially when ClearCase hacks with the file system), you can end up with a lot of unintentional interactions that can cause something to work in some situations, but not others.

To figure out the issue you're having with a system call, you'll have to assume the error could be in ClearCase, the cmd.exe shell, the xcopy command, or Perl. By not using the system command, you've simplified your problem, and many times actually speed up the process.

like image 90
David W. Avatar answered Apr 29 '23 07:04

David W.