File::Copy's copy puts a lot effort in being portable.
It's well tested.
It doesn't launch a seperate process, so it's faster and uses less memory. Instead, it uses a system call (or Perl code if the OS doesn't have such a call).
It can copy from/to file handles instead of just from/to files.
Its arguments are not subject to shell interpretation. (The way in which you used system is buggy and unsafe.)
It's makes checking for success much easier.
It provides meaningful error messages in $!, on most systems.
On the other hand,
Your expression is not portable.
It's not well tested. In fact, there are bugs.
It launchs *two* seperate processes, so it's slower and uses more memory.
It can't copy from/to file handles, just from/to files.
Its arguments are subject to shell interpretation (although that can be fixed). The way in which you used system is buggy and unsafe. (Bug 1)
It thinks it succeeds even if the copy fails, as long as the shell was successfully loaded. (I think.) (Bug 2)
$! does not contain what you think it does here. It definitely does not contain why the copy failed when it does. (Bug 3)