Sravan
Sravan

Reputation: 2019

ssh perl script not running

I am trying to write a script that will ssh to a remote machine in perl.

I'm not sure what's wrong but when I run the script, it prompts me for the root password and ends up with blank output after I give the password.

Here's my script:

#!/usr/bin/perl
use strict;
use warnings;

my @id=`ssh expert\@x.x.x.x`;
print"@id";

Upvotes: 1

Views: 1062

Answers (2)

Borodin
Borodin

Reputation: 126722

That is what you have asked your program to do. This line

`ssh expert\@x.x.x.x`
  • Starts a new subprocess running ssh with the given parameters
  • Exits that subprocess and returns any text output from ssh

You presumably need to interact with the remote system once you have connected, so you either need the perl process to connect to the remote system, or you need to be able to listen and talk to the subprocess that hash connected before it exits

The first is by far the simplest solution. If you use the Net::OpenSSH module and read its documentation then you will see that you can open a connection by creating an object. You can then send commands and retrieve the output using that object's capture method

Upvotes: 2

J Singh
J Singh

Reputation: 162

I would advice against using system ssh command inside perl code for below reasons:

  1. It makes parsing output difficult
  2. Error handling becomes difficult
  3. Less programming flexibility

Rather, use a CPAN library, e.g. Net::SSH::Perl for firing SSH commands from Perl code.

Its simple to open a shell using this module as described below:

$ssh->shell

Opens up an interactive shell on the remote machine and connects it to your STDIN. This is most effective when used with a pseudo tty; otherwise you won't get a command line prompt, and it won't look much like a shell. For this reason--unless you've specifically declined one--a pty will be requested from the remote machine, even if you haven't set the use_pty argument to new (described above).

This is really only useful in an interactive program.

In addition, you'll probably want to set your terminal to raw input before calling this method. This lets Net::SSH::Perl process each character and send it off to the remote machine, as you type it.

To do so, use Term::ReadKey in your program:

    use Term::ReadKey;
    ReadMode('raw');
    $ssh->shell;
    ReadMode('restore');

Below is a quick example that demonstrates how easy it would be to use the same module to fire and parse command output:

  use Net::SSH::Perl;
    my $ssh = Net::SSH::Perl->new($host);
    $ssh->login($user, $pass);
    my($stdout, $stderr, $exit) = $ssh->cmd($cmd);

Link to Net::SSH::Perl cpan documentation: http://search.cpan.org/~schwigon/Net-SSH-Perl-1.42/lib/Net/SSH/Perl.pm

Another module which I prefer to use is Net::OpenSSH: http://search.cpan.org/~salva/Net-OpenSSH-0.70/lib/Net/OpenSSH.pm

use Net::OpenSSH;

  my $ssh = Net::OpenSSH->new($host);
  $ssh->error and
    die "Couldn't establish SSH connection: ". $ssh->error;

  $ssh->system("ls /tmp") or
    die "remote command failed: " . $ssh->error;

  my @ls = $ssh->capture("ls");
  $ssh->error and
    die "remote ls command failed: " . $ssh->error;

  my ($out, $err) = $ssh->capture2("find /root");
  $ssh->error and
    die "remote find command failed: " . $ssh->error;

  my ($rin, $pid) = $ssh->pipe_in("cat >/tmp/foo") or
    die "pipe_in method failed: " . $ssh->error;

  print $rin "hello\n";
  close $rin;

Upvotes: 1

Related Questions