I'll avoid repeating what's already been said. As a point of note though:
foreach my $file (@$exc) {
if($_ eq $file) {
$skip =1;
}
}
is broken, since it'll keep looping through checking for exclusions even if it's already found that this file or directory is in fact excluded from being backed up. Realistically, in a small, simple backup script like this, run on your own computer most of the time, it probably wouldn't matter. But it IS generally a good idea to leave a loop when you no longer need it to execute. :)
foreach my $file (@$exc) {
if($_ eq $file) {
$skip =1;
}
last if $skip;
}