+6  A: 

If a command might go haywire and hang your script, a good defense is to use alarm and a SIGALRM handler to make the command time out.

sub system_with_timeout {
    my ($timeout, @command) = @_;
    local $SIG{ALRM} = sub { die "Timeout\n" };
    my $result;
    if ($timeout > 0) { alarm $timeout; }
    eval {
        $result = system(@command);
    };
    if ($@ =~ /Timeout/) {
        warn "@command timed out.\n";
        return -1;
    }
    return $result;
}

Check the return values to make sure your command was successful or whether it timed out.

my $z = system_with_timeout(30, "systemsetup -setusingnetworktime off");
if ($z == 0) {
    # success ...
} elsif ($z == -1) {
    # timed out ... try it again ?
} else {
    # failed for some other reason ...
}
mobrule
@mobrule - i added extra suggestion in my answer in case `systemsetup` does not actually signal errors via return code, which sadly happens fairly often
DVK
@DVK - Indeed; that appears to be true in this case.
NReilingh
I would recommend returning `undef` on timeout (kind of a grade "Incomplete"). `system` will always return a value. Using -1 causes a collision with programs that return -1. Since this is an error situation, you want the best error reporting possible.
Axeman
@DVK Good suggestion. It is straightforward to implement `backticks_with_timeout` or `open-|_with_timeout` functions with the same features. @Axeman - `system` returns 0 on success. I'd hate to execute the wrong code because I checked if `$returnval == 0` and forgot to check if `defined $retval` when I changed a `system` to a `system_with_timeout` call.
mobrule
+2  A: 

If you don't care about the error itself (e.g. it is just a warning message), by all means re-direct the STDOUT/STDERR of the command; although I'd personally recommend re-directing to a /tmp logfile (and not /dev/null) in case you ever need to troubleshoot some OTHER error.

If you actually wish to take a specific action upon such an error, you can either check the return code (see mobrule's answer), or if the command always returns 0, capture the putput and filter it for error:

my @script_out = `systemsetup -setusingnetworktime off`;
# better yet use open with a pipe instead of backticks 
if (grep {/writeconfig.*dropping incoming DO message/} @script_out {
    # do error handling
}
DVK