[Chicago-talk] perl touch
Steven Lembark
lembark at wrkhors.com
Wed May 10 09:22:59 PDT 2006
> Touch never uses stdout, so capturing it won't do much good. Your
best bet
> is to simply do
>
> system 'touch', $foo or die "Failed to start touch!";
> die 'Call to touch failed!' if $?;
Touch returns true on failure (e.g., "touch /foo/bar/bletch"
on a system without directory /foo exits with 1). An "or"
leaves you with a true system return on failure and thus
bypassing the sanity check.
This is a common problem since the definition of "success"
and "true" are reversed in many situations. C (and most
shell) use false for success; most perly code use false
for failure.
This requires something like:
system "$cmd"
and die "Roadkill: '$cmd' returned shell true";
The "foo and die" notation is confusing to most people,
since they expect and "and" to follow successful completion.
A better way is to investigate $? for death by signal,
etc, after the system call and see what that gives you.
if ($? == -1)
{
print "failed to execute: $!\n";
}
elsif ($? & 127)
{
printf "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
}
elsif( my $sig = ( $? & 0xFF ) )
{
# you died with signal $sig
}
else
{
my $return = $? >> 8;
# which doesn't really tell you much unless you
# KNOW what the thing is supposed to return on
# error: what if it returns true on success?
}
Parallel::Queue has a complete example of handling
system calls (pretty much the above ladder with
better reporting):
<http://search.cpan.org/~lembark/Parallel-Queue-0.03/lib/Parallel/Queue.pm>
> If you *really* must capture the error message, then this should work:
>
> $error = `system 'touch ' . quotemeta($foo) . ' 2>&1'`;
> die $error if $error;
--
Steven Lembark 85-09 90th Street
Workhorse Computing Woodhaven, NY 11421
lembark at wrkhors.com +1 888 359 3508
More information about the Chicago-talk
mailing list