The problem with this code is that the shell script isn't being killed.
alarm just arranges for a signal to be delivered to the Perl process, upon which the signal handler throws an exception (die "alarm\n") which in turn causes the Perl script to continue after the eval {} block. The shell script doesn't know anything of this and happily keeps running.
It turns out that the shell script is not even executed.
This is most likely an unrelated problem. Makes me wonder how/why it did run before with the identical system command...