best practices for checking system return values for piped commands?
markjugg
created: 2006-05-01 16:06:21
This little failing test case illustrates my question:

# Test error checking for piped system calls
# We use 'boom', a non-existent command, for testing.

use Test::More qw/no_plan/;
use strict;

ok_system_call("true");
ok_system_call("true|true");

not_ok_system_call("boom");
not_ok_system_call("boom|boom");
not_ok_system_call("true|boom");
not_ok_system_call("boom|true");

#################################3

sub ok_system_call {
    my $test = shift;
    my $expect_success = shift;
       $expect_success = 1 if not defined $expect_success;

    my $ok = (system($test) == 0);
    # my $exit_code = $? >> 8;
    # diag "exit code was: $exit_code";

   return $expect_success ? ok($ok, $test) : ok(!$ok, $test);
}

sub not_ok_system_call {
    my $test= shift;
    return ok_system_call($test,0);
}
The error checking doesn't work correctly on the last one ("boom|true"), so it fails. I believe this happens because although boom fails, something is sent through the pipe, and 'true' succeeds on the other end of the pipe. What's the best practicing for error checking a piped command so this case is covered?

[markjugg|Mark Stosberg]

Re: best practices for checking system return values for piped commands?
created: 2006-05-01 16:17:01
The error checking doesn't work correctly on the last one ("boom|true"), so it fails. I believe this happens because although boom fails, something is sent through the pipe, and 'true' succeeds on the other end of the pipe.

On a Linux 2.6, with a bash shell:

$ boom|true; echo $?
bash: boom: command not found
0
$ _

This is because, according to the documentation of my shell, The return status of a pipeline is the exit status of the last command, unless the pipefail option is enabled. So, if your shell works like bash in this respect, your tests are returning the results they should.

--
David Serrano

Re: best practices for checking system return values for piped commands?
created: 2006-05-01 21:35:17
Note that bash also has a PIPESTATUS (sp?) env var array that allows you to get the "$?" of the intermediate commands in the pipeline.
Re^2: best practices for checking system return values for piped commands?
created: 2006-05-01 22:41:02
I second the use of bash-es PIPESTATUS, I've used it in code like this:
my %cmds = ( 'bash' => '/usr/local/bin/bash',
             'gzip' => '/usr/bin/gzip',
             'lzop' => '/usr/bin/lzop',
             'wc'   => '/usr/bin/wc' );


my @zip_results = `$cmds{'bash'} -c '$cmds{$compress} -dc $file | $cmds{'wc'} -c ; echo \${PIPESTATUS\@}'`;
The last line of @zip_results has the status of both the 'compress' command and the 'wc' command.
Re: best practices for checking system return values for piped commands?
created: 2006-05-02 08:39:35
Just to add a little to what others have said, 'true' is not the best possible choice for a 2nd command since:
1. it isn't reading it's stdin in so won't detect anything wrong.
2. 'true' tries its hardest to live up to its name, always exiting with status zero.
Bill H
perl -e 'print sub { "Hello @{[shift]}!\n" }->("World")'
Re^2: best practices for checking system return values for piped commands?
created: 2006-05-04 11:27:26

"true" is a great choice to illustrate my test, as it is a great example of an utility which "succeeds" even with no input piped to it.

perlmonks.org content © perlmonks.org and Anonymous Monk, billh, eXile, Hue-Bond, markjugg

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03