Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

File::Copy versus cp/mv

by mce (Curate)
on Oct 01, 2003 at 15:44 UTC ( [id://295656]=perlquestion: print w/replies, xml ) Need Help??

mce has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

I am trying to convince my coworkers to stop using

system("cp $foo $bar"); system("mv $foo $bar");
to
use File::Copy; copy($foo,$bar); move($foo,$bar);
But they just don't listen. What are good arguments to convince them. We only develop on/for unix, so portability is not a good reason.

I though of:
1. The returncodes are correct (1 => OK, 0 => NOK)
2. It prevents forking a new process.

But what else??
---------------------------
Dr. Mark Ceulemans
Senior Consultant
BMC, Belgium

Replies are listed 'Best First'.
Re: File::Copy versus cp/mv
by Abigail-II (Bishop) on Oct 01, 2003 at 15:59 UTC
    "Portability" between platforms is the strongest argument in favour of File::Copy. "Portability" on the same platform (as in "behave the same as other applications do") is a strong argument in favour of using cp.

    Personally, I favour 'rename' for renaming files within the same filesystem, 'system mv' for moving files over filesystem boundaries, and 'system cp' for copying files. My main beef I have against File::Copy is that it doesn't it doesn't respect execution bits. Furthermore, 'cp' (and 'mv') can take multiple arguments (moving or copying a bunch of files into a directory), and options (-a, -f, -R). Oh, and the last argument of 'cp' can be a directory, which I find extremely useful. Perhaps File::Copy::copy can too, but not according to its manual page.

    On a more abstract level, why are you trying to convince your coworkers to stop using system? You can't even come up with reasons they should - you are asking here for arguments in your favour! If you can't find convincing arguments yourself, it may be a sign you are not fighthing a worthwhile battle.

    Abigail

Re: File::Copy versus cp/mv
by Aristotle (Chancellor) on Oct 01, 2003 at 16:49 UTC

    Depends. Are you doing this from within a performance critical program? If this were code running under mod_perl, f.ex, I wouldn't be pleased that someone forks an entire Apache willy nilly.

    But if they're simple maintenance scripts or such, there's not much wrong in using the Unix toolbox if Unix is what you're going to run on.

    There's something they need convincing of though: avoid the shell whenever you can reasonably do so.

    system(cp => $foo, $bar); system(mv => $foo, $bar);
    And if filenames can contain metacharacters, glob them yourself. Going through the shell can easily cause unexpected behaviour if you're not careful, and it's very easy to not be careful enough.

    Makeshifts last the longest.

Re: File::Copy versus cp/mv
by dragonchild (Archbishop) on Oct 01, 2003 at 16:55 UTC
    File::Copy doesn't do directories. It also doesn't respect execution bits. What it does do is copy faster than cp. (And, you can increase that speed to the max your hardware can handle.)

    I have wrapped around File::Copy to meet the needs of the application I work with, handling directories and copying to a temp-name, then moving, so as to only have the name appear when the file is fully copied. (500M over a network can be less than instantaneous, but File::Copy does help.)

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: File::Copy versus cp/mv
by vek (Prior) on Oct 01, 2003 at 19:15 UTC

    While there might be some good reasons to use the Unix toolkit I've seen people shell out for the simple reason that they had not taken the time to figure out you can do it in Perl.

    I've pointed out to a cowoker that you really don't need to do this...

    my @files = `ls *`;
    ...when this would suffice:
    my @files = <*>;

    I've also seen the following crop up from time to time:

    my $now = `date`; system("rm testfile");

    -- vek --
Re: File::Copy versus cp/mv
by samtregar (Abbot) on Oct 02, 2003 at 05:29 UTC
    Two good reasons: 1) security, when the filenames are coming from external sources and 2) the ability to handle strange characters in filenames (spaces, pipes, etc). These are good arguements, but if it were me I'd just tell them it's faster. Most programmers I know are slaves to (percieved) performance.

    -sam

      Both reasons you name are arguments to forgo the shell, but not reason enough to avoid system alltogether.. :)

      Makeshifts last the longest.

Re: File::Copy versus cp/mv
by ed (Initiate) on Jan 02, 2008 at 14:09 UTC
    It's pretty easy to convince them. Just insist that instead of writing fragile code that blithely ignores error returns, they check and report them properly.
    my $cmd = "cp $foo $bar"; my $r = system($cmd); if ($r) { if ($? == -1) { die "failed to execute '$cmd': $!\n"; } elsif ($? & 127) { my $msg = sprintf "'$cmd' failed with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; die $msg; } else { die "'$cmd' exited with value %d\n", $? >> 8; } }
    This is based on the example code in perlfunc(1). Faced with writing all that just to get a correct error message on failure, any developer would prefer to encapsulate the code in some routine, called... oh, I don't know, perhaps copy()? Now while File::Copy's interface is not as crufty as system()'s, you still have to check for errors explicitly:
    copy($foo, $bar) or die "cannot copy $foo to $bar: $!";
    But that's a big improvement for any programmer who wants to be lazy but still write correct code. Others have mentioned the need to use multi-argument system(), otherwise your code will have (perhaps exploitable) bugs when passed filenames containing spaces or shell characters.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://295656]
Approved by bunnyman
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (7)
As of 2024-03-28 18:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found