1

I need to create a script that will work on CentOS 5.x and CentOS 6.x boxes. CentOS 5.x uses Perl 5.8 and CentOS 6.x uses Perl 5.10. The goal is to be able to ssh into a box, that has a key exchange in place, then run python -V, to determine if the default version is python 2.6.

I'm guessing if I get a script that works with Perl 5.8, that it'll work for 5.10 as well. I made some progress with Net::SSH:Any to have to throw it away, as it looks like it works with Perl 5.12 and newer.

I've tried IPC::System::Simple and qx as well, but haven't had luck capturing the output.

Some of my failed attempts:

Fail 1:

use IPC::System::Simple qw(system systemx capture capturex);
my $output = capture("/usr/bin/ssh root\@10.100.10.56 python -V");
print "out: " . $output . "\n";

Fail 2:

my $output = qx(ssh root\@10.100.10.56 python -V);
print "out: " . $output . "\n";

Fail 3:

my @output = qx(ssh root\@10.100.10.56 python -V);
print "@output\n";

I'm not sure if the call of ssh is playing with anything and am in desperate need of a sanity check. When the command is run, the output is shown on the screen, but not stored in the variable, which I can do substring checks against. The $output variable is left blank. If I'm missing something, please let me know. Thanks :)

James Oravec
  • 19,579
  • 27
  • 94
  • 160
  • 2
    `python -V` may write to `STDERR` instead of `STDOUT`. Also, why not just use a different module for SSH like `Net::OpenSSH`? – ThisSuitIsBlackNot Sep 26 '14 at 21:52
  • I looked into `SSH`, `SSH2`, and `OpenSSH`. I've tried to simplify things and just run the command directly to get things working. Is there a way to get `qx` to capture stderr too? – James Oravec Sep 26 '14 at 21:54
  • 2
    There is. See [How to capture both STDOUT and STDERR in two different variables using Backticks in Perl](http://stackoverflow.com/q/8384619/176646). However, you should really avoid using bacticks/`system` when there is a pure Perl equivalent. `Net::OpenSSH` has this nice [`system`](https://metacpan.org/pod/Net::OpenSSH#ssh-system-opts-cmd) method that lets you control `STDIN`, `STDOUT`, `STDERR`, and more. – ThisSuitIsBlackNot Sep 26 '14 at 22:02
  • Looks like you found the same link as me a couple minutes later :) I looked at Net::OpenSSH on cpan and when I went to the very bottom it looks like it is support with 5.10 and later, so wouldn't work for my CentOS 5.x boxes. I'd prefer to use the newer stuff anyway, but I need to support existing customers :) – James Oravec Sep 26 '14 at 22:14
  • 1
    I don't know what you're talking about. `Net::OpenSSH` passes all tests on [CPAN Testers](http://www.cpantesters.org/distro/N/Net-OpenSSH.html?oncpan=1&distmat=1&version=0.62) for 5.8.x. I think you're just looking at the license terms, which have nothing to do with whether a module will run on earlier Perl versions. – ThisSuitIsBlackNot Sep 26 '14 at 22:18
  • 1
    IIRC, Net::SSH::Any only requires perl 5.8. – salva Sep 29 '14 at 08:22

1 Answers1

2

Figured it out from ThisSuitIsBlackNot's advice. I found Getting STDOUT, STDERR, and response code from external *nix command in perl which showed me how to update my code to get stderr too, which is as follows:

my $output = qx(ssh root\@10.100.10.56 python -V 2>&1);
print "out: " . $output . "\n";

This gave me what I needed. Thx!

Community
  • 1
  • 1
James Oravec
  • 19,579
  • 27
  • 94
  • 160
  • I'm glad I don't have that layer of complexity to have to fight with too :) Might work with cygwin, but would be a side project :) – James Oravec Sep 26 '14 at 22:11
  • My point is, Python is cross-platform, so there's no reason your command to check the version should be restricted to a single OS. If you use a module like `Net::OpenSSH` instead of backticks, you don't have to worry about OS-specific quoting and I/O redirection. `my @cmd = qw(python -V); $ssh->system({ stderr_to_stdout => 1 }, @cmd) or die $ssh->error;` – ThisSuitIsBlackNot Sep 26 '14 at 22:16
  • @ThisSuitIsBlackNot: Net::OpenSSH does not work on Windows, not even under Cygwin Perl. That's the main reason that pushed me to create Net::SSH::Any. – salva Sep 29 '14 at 08:22
  • 1
    @salva You mean it doesn't *run* on Windows, correct? I'm just talking about connecting to a remote Windows machine. Of course, I've never tried it so I could just be talking out my you-know-what. – ThisSuitIsBlackNot Sep 29 '14 at 14:20
  • 1
    @ThisSuitIsBlackNot, yes, Net::OpenSSH can connect to Windows machines. Version 0.62 also got support for quoting commands for Win32 and `cmd.exe`. – salva Sep 29 '14 at 14:53
  • @salva Good to know. BTW, the only reason I recommended `Net::OpenSSH` is that I took the OP's statement about `Net::SSH::Any` only working for 5.12+ at face value. In retrospect, I should have double checked that. That, and the statement "The API is not stable and may change between releases" in the documentation. – ThisSuitIsBlackNot Sep 29 '14 at 15:01
  • Net::SSH::Any provides just a subset of Net::OpenSSH features, but it does work on Windows. If you only need your scripts to work on Linux/Unix systems, Net::OpenSSH is actually a better option. – salva Sep 29 '14 at 15:05