eonarts has asked for the wisdom of the Perl Monks concerning the following question:

I need to run a remote command. I will not know the language before hand. This seemed like a simple problem that shell could handle but I need more error checking. But most importantly I needed a hash so off to perl.

I've got Net::OpenSSH working if I just use capture with no args but I need to send an arg & this causes an err to be flagged.

my @output = $ssh->capture("$cmd $arg1 $arg2");

if($ssh->error) { if($ssh->error) { $myhash{"$cmd" = "FAIL"; } else { $myhash{"$cmd" = "Ok"; } }

I've got filehandles set up and everything gets printed to these (a log & an err log). But when I add the args to the $cmd the err file says it doesn't know a command by that name (the 1st arg is a build number so its a number).

I've spent lots of hours searching & tried many things but I need the details of the output not just a 0 or 1.

I've read the CPAN docs & tried many things but none worked but to send the $cmd...

thoughts?

Replies are listed 'Best First'.
Re: Net::OpenSSH capture and cmd w/args
by Anonymous Monk on Aug 04, 2011 at 15:39 UTC
    It will probably work if you use $cmd with an absolute path, e.g. /usr/local/bin/whatevercmd?
    Add warn "($cmd) ($arg1) ($arg2)" as diagnostic output.
Re: Net::OpenSSH capture and cmd w/args
by eonarts (Novice) on Aug 04, 2011 at 16:00 UTC

    Valid code as per request.

    #!/usr/bin/perl use strict; use warnings; use Time::HiRes qw/ usleep gettimeofday tv_interval/; use File::Basename; use Net::OpenSSH; use Expect; ################################# ## Configurables here ################################# our $test_host="myhost"; our $ssh_user="myuser"; our $HOME="/home/myuser"; our $dir="${HOME}/mytests"; our $ARG1=777; ################################# ## Variables here ################################# our %test_results ; our $Y = "OK"; our $N = "FAIL"; our @output_to_print ; my ($file, $fname,$text_to_print); our $now=`date +%m%d%Y_%H%M%S`; chomp($now); my ($stderr_fh, $stdout_fh); my $stdoutfile = "/tmp/$ARG1$now.log"; my $stderrfile = "/tmp/$ARG1$now.err"; our $LOG="/tmp/${ARG1}_${now}.log"; ################################# ## Main ################################# open $stdout_fh, '>>', "$stdoutfile" or die "cannot open stderr file"; open $stderr_fh, '>>', "$stderrfile" or die "cannot open stdout file"; # open a connection to the test server my $ssh = Net::OpenSSH->new("$ssh_user\@$test_host",default_stderr_fh +=> $stderr_fh, default_stdout_fh +=> $stdout_fh ); $ssh->error and die "SSH connection failed: " . $ssh->error; # Get the files to run my @files = $ssh->capture("ls $dir "); $ssh->error and die "remote ls command failed: " . $ssh->error; foreach $file(@files){ my $full_file="${dir}/$file"; my $fname = $file; $fname =~ s{\.[^.]+$}{}; print "$fname \n"; $text_to_print="test: $full_file Log: $LOG \n"; print $stdout_fh "$text_to_print \n"; my @output = $ssh->capture("$full_file "); if($ssh->error) { $test_results{"$fname"} = "$N"; } if(grep(/\b$Y\b/,@output)) { $test_results{"$fname"} = "$Y"; } else { if (grep(/\b$N\b/,@output)) { $test_results{"$fname"} = "$N"; } } print $stdout_fh "@output \n"; } print $stdout_fh "\nTest results\n#################\n"; while ((my $test, my $result) = each(%test_results)) { print $stdout_fh "$test, $result\n"; }

    I've tried the following with no success

    # DOESNT WORK?? the $ARG1 causes problems? my @output = $ssh->capture("$full_file $ARG1 $LOG"); # doesnt work my( $in, @output, $err, $pid ) = $ssh->open3("$full_file $ARG1 $LOG"); # DOESNT WORK?? my @output = $ssh->capture(stdin_data => "$full_file $ARG1 $LOG ");
      $full_file probably contains a linefeed. Please chomp first...

        ARG! really? really? I thought that was a silly reply - which probably meant it was the correct answer.

        ::hangs head in shame::

        THAT WAS THE ANSWER! thank you thank you thank you!

        my $full_file="${dir}/$file"; chomp($full_file);

        I need more sleep & coffee...

      Does $full_file exist? Is it executable? Maybe you want something like $ssh->capture("cat $full_file");?