#!/usr/bin/perl # copy_without_xattr # Files on OS X can have resource forks and other extended attributes and # as of Tiger (10.4) the 'cp' command copies these extended attributes. # This script copies the file(s) given as command-line args # to the destination given as the last command-line arg # but suppresses the copying of extended attributes. # I.e. it does the same thing as /bin/cp except for the extended attributes # This is useful when the destination is on a non-HFS volume # in order to avoid the "._" files that would otherwise be produced. # (These "._" files hold the extended attributes and resource fork info) # # Cameron Hayne (macdev@hayne.net) Sept 2005 use strict; use warnings; use File::Basename; my $scriptName = basename($0); if (scalar(@ARGV) < 2) { print("usage: $scriptName file1 [file2 file3 ...] destDir"); exit 1; } my $destDir = pop(@ARGV); my @files = @ARGV; die "$scriptName: $destDir is not a directory\n" unless -d $destDir; die "$scriptName: $destDir is not writable\n" unless -w $destDir; foreach my $file (@files) { die "$scriptName: $file is not a file\n" unless -f $file; die "$scriptName: File $file does not exist or is not readable\n" unless -r $file; } # We set an environment variable to disable the copying of extended attributes # Unfortunately, /bin/cp does not look at COPY_EXTENDED_ATTRIBUTES_DISABLE # or this script would be as simple as: /bin/cp @ARGV # We use '/usr/bin/tar' (which does look at COPY_EXTENDED_ATTRIBUTES_DISABLE) # to simulate the effect of /bin/cp # Note: to test future versions of 'tar' to see if they are using this variable, # you could use the command: # 'strings /usr/bin/tar | grep COPY_EXTENDED_ATTRIBUTES_DISABLE' $ENV{'COPY_EXTENDED_ATTRIBUTES_DISABLE'} = "true"; my $tmpFile = "/tmp/$scriptName$$"; my $tarCreateCmd = "/usr/bin/tar -cf $tmpFile"; foreach my $file (@files) { my $fname = basename($file); my $dname = dirname($file); # we use the "-C" option so that the archive will have the basenames $tarCreateCmd .= " -C $dname $fname"; } system($tarCreateCmd) == 0 or die "$scriptName: failed to create tar file: $!\n";; chdir($destDir) or die "$scriptName: failed to chDir to $destDir: $!\n"; my $tarExtractCmd = "/usr/bin/tar -xf $tmpFile"; system($tarExtractCmd) == 0 or die "$scriptName: failed to extract tar file: $!\n";; unlink($tmpFile) or die "Failed to unlink $tmpFile: $!\n";