2010-05-17 38 views
9

Quiero SSH a un servidor y ejecutar un comando simple como "id" y obtener su salida y almacenarlo en un archivo en mi servidor primario. No tengo privilegios para instalar Net::SSH lo que haría mi tarea muy fácil. Por favor, dame una solución para esto. Intenté usar back-ticks pero no puedo almacenar la salida en la máquina desde la cual se ejecuta mi script.¿Cómo puedo ssh dentro de un script de Perl?

+8

¿Estás seguro de que no tienes los privilegios que necesitas para instalar Net :: SSH? http://www.shadowcat.co.uk/blog/matt-s-trout/but-i-cant-use-cpan/ – Quentin

+0

Hay mucha información sobre la instalación de módulos Perl en su propio espacio. Incluso está en Stackoverflow: http://stackoverflow.com/questions/251705/how-can-i-use-a-new-perl-module-without-install-permissions –

+11

Mientras me doy cuenta de que esta es una vieja pregunta, siento que Necesito comentar ¿Por qué la mayoría de los programadores se vuelven tontos cuando otros programadores solicitan ayuda porque no tienen permitido usar código abierto y luego comentan qué fácil es instalar el código y usarlo? Todavía hay empresas que no permiten que sus programadores usen código externo a menos que sea sometido a rigurosas pruebas de funcionalidad, rendimiento, seguridad, etc. Mi empresa es una así. Prefieren que reinventes la rueda que usar código externo y haces todo lo posible para evitar su uso. –

Respuesta

0

Si tiene la configuración de las llaves del host ssh, simplemente puede ejecutar el comando del sistema ssh y luego especificar el comando que se ejecutará en la máquina después de eso. Por ejemplo:

`ssh [email protected] id` 

Debería poder masticar/almacenar esa salida.

7

Siempre puede instalar módulos localmente, y ese es el método que debe considerar; Sin embargo, usted debería ser capaz de salirse con la

#!/usr/bin/perl 

use strict; 
use warnings; 

my $id = qx/ssh remotehost id 2>&1/; 

chomp $id; 

print "id is [$id]\n" 
0

Suponiendo que estás en un entorno como yo donde no se puede añadir módulos adicionales y no se puede crear un archivo de Identidad, a continuación, puede utilizar esta secuencia de comandos como punto de partida.

Si puede configurar las claves SSH a continuación, sólo tiene que utilizar los acentos abiertos comando ya publicado, aunque es posible que tenga la opción -i

#!/usr/bin/perl 
use warnings; 
use strict; 
use Expect; 
use Data::Dumper; 

my $user = 'user'; 
my $pw = 'password'; 
my $host = 'host'; 
my $cmd = 'id'; 

my $exp = new Expect; 
$exp->log_file("SSHLOGFILE.txt"); 
$exp->log_stdout(0); 
$exp->raw_pty(1); 


my $cli = "/usr/bin/ssh $user\@$host -o StrictHostKeyChecking=no -q $cmd"; 

$exp->spawn($cli) or die "Cannot spawn $cli: $!\n"; 

$exp->expect(5, 
[ qr /ssword:*/ => sub { my $exph = shift; 
          $exph->send("$pw\n"); 
          exp_continue; }]); 

my $read = $exp->exp_before(); 
chomp $read; 
print Dumper($read); 

$exp->soft_close(); 
+1

Esperar no es un módulo estándar ... – lbalazscs

13

La mejor manera de ejecutar comandos de forma remota a través de SSH es

$ ssh [email protected] "command" > output.file 

Puede usar esto en bash o en perl. Sin embargo, si desea usar Perl, puede instalar los módulos Perl en su ruta de directorio local como lo sugiere Brian en su comentario o en las Preguntas frecuentes de Perl en "How do I keep my own module/library directory?". En lugar de usar Net :: SSH, sugeriría utilizar Net :: SSH :: Perl con el ejemplo siguiente.

#!/usr/bin/perl -w 
use strict; 
use lib qw("/path/to/module/"); 

use Net::SSH::Perl; 

my $hostname = "hostname"; 
my $username = "username"; 
my $password = "password"; 

my $cmd = shift; 

my $ssh = Net::SSH::Perl->new("$hostname", debug=>0); 
$ssh->login("$username","$password"); 
my ($stdout,$stderr,$exit) = $ssh->cmd("$cmd"); 
print $stdout; 
+0

@salman: ¿Alguna actualización sobre esto? – Space

1

Si está utilizando acentos abiertos Prueba esto:

my @output = `ssh [email protected] "which perl"`; 

print "output: @output"; 

esto sólo es útil si tiene una clave pública que el comando anterior no se le pedirá la contraseña.

2

o, suponiendo que las claves de host están presentes y que quieren hacer algo con que la salida de comandos ...

open(SSH,"/usr/bin/ssh you\@server ps aux |") or die "$!\n"; 
while (<SSH>) { 
    # do stuff with $_ 
} 
close SSH; 
0
use warnings; 
use strict; 
use NET::SSH2; 

sub is_sshalive; 

my $host = "ip"; # use the ip host to connect 
my $user = "UNAME"; # your account 
my $pass = "PASSWD"; # your password 
my $cmd; 
my $ssh2 = Net::SSH2->new(); 
$ssh2->debug(1); 
if ($ssh2->connect($host)) { 
    #if ($ssh2->auth_password($user,$pass)) { 
    if ($ssh2->auth_keyboard($user,$pass)) { 
     print "\n Executing command...\n"; 
     $cmd = "ls"; 
     print " ==> Running $cmd\n"; 
     if(is_sshalive($ssh2) == 1) { 
       print "\nSSH connection died"; 
       exit 1; 
     } else { 
      run_testsuite($cmd, $ssh2); 
     } 
    } else { 
     warn "ssh auth failed.\n"; 
     exit 1; 
    } 
} else { 
    warn "Unable to connect Host $host \n"; 
    exit 1; 
} 
print "test passed done 0\n"; 


sub run_testsuite { 
    my $cmd = $_[0]; 
    my $ssh2 = $_[1]; 

    my $chan2 = $ssh2->channel(); 
    $chan2->shell(); 
    print $chan2 "$cmd \n"; 
    print "LINE : $_" while <$chan2>; 
    $chan2->close; 
    return 0; 
} 

sub is_sshalive { 
    my $ssh2 = $_[0]; 
    if ($ssh2->poll(1000) == 0) { 
     return 0; # passed 
    } else { 
     return 1; #failed 
    } 
} 
1

tuve un problema similar, y después de mucho buscar he encontrado un sencillo opción. Usé qx() y ejecuté los comandos ssh como lo haría normalmente. El problema es que tuve que capturar stderr y stdout.

El siguiente es un ejemplo de lo que solía:

my $output = qx(ssh root\@$curIP python -V 2>&1); 

Se ejecuta el comando python -V, que da salida a la información de la versión para stderr. En este ejemplo, mi dirección IP se almacenó en la variable $curIP. Por último, el 2>&1 ayuda a capturar stdout y stderr. No especifiqué una contraseña, ya que tengo la configuración de intercambio de claves. Espero que esto ayude.

0

Sé que este es un hilo muy viejo, pero desde que encuentro el mismo problema encontré otra solución útil en caso de que alguien esté usando Linux.

#!/usr/bin/perl 
use strict; 
use warnings; 
use Data::Dumper; 

my $host = $ARGV[0]; 
my $port = $ARGV[1]; 
my $cmd = $ARGV[2]; 

my @output = readpipe("ssh -p ". 
       $port." ". 
       $host." ". 
       $cmd.""); 

chomp @output; 

print Dumper \@output; 

__END__ 

perl sample.pl 127.0.0.1 22 "which perl" 
Ubuntu 16.04.1 LTS 
$VAR1 = [ 
      '/usr/bin/perl' 
     ]; 

Esto asume que ha configurado ssh-keys para que no se requiera la entrada del usuario. No quería tener valores codificados, esta es la mejor manera para mí que funcionó mejor. Estoy usando readpipe para lograr eso.

Espero que esto ayude a tener una solución en caso de una codificación no dura.

Cuestiones relacionadas