That's not quite right; $@ will get the exception (aka "die" message). Anything directly written out to STDERR or STDOUT will not be caught, unless you tie those filehandles (only works for output by perl) or reopen them. If the output is due to a warn, you can catch it with a $SIG{__WARN__} handler.
Oh OK right I see. Part of my error is the shell, and part is perl.
Lifted this from the open docs.
open OLDERR,">&",\*STDERR or die "Can't dup STDERR: $!";
open STDERR,'>>',"foo.out" or die "Can't redirect STDERR: $!";
eval 'use Cache::File';
open STDERR, ">&OLDERR" or die "Can't dup OLDERR: $!";