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
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 | [reply] |
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.
| [reply] [d/l] |
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.
| [reply] |
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");
| [reply] [d/l] [select] |
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
| [reply] |
|
Both reasons you name are arguments to forgo the shell, but not reason enough to avoid system alltogether.. :)
Makeshifts last the longest.
| [reply] |
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. | [reply] [d/l] [select] |
|
|