2010-05-17 14 views
9

Voglio SSH su un server ed eseguire un comando semplice come "id" e ottenere l'output di esso e memorizzarlo in un file sul mio server primario. Non ho i privilegi per installare Net::SSH che renderebbe il mio compito molto facile. Per favore forniscimi una soluzione per questo. Ho provato a utilizzare back-ticks ma non riesco a memorizzare l'output sulla macchina da cui viene eseguito il mio script.Come posso ssh all'interno di uno script Perl?

+8

Sei sicuro di non disporre dei privilegi necessari per installare Net :: SSH? http://www.shadowcat.co.uk/blog/matt-s-trout/but-i-cant-use-cpan/ – Quentin

+0

Ci sono molte informazioni sull'installazione dei moduli Perl nel tuo spazio. È anche su Stackoverflow: http://stackoverflow.com/questions/251705/how-can-i-use-a-new-perl-module-without-install-permissions –

+11

Mentre mi rendo conto che questa è una vecchia domanda, mi sento ho bisogno di commentare. Perché la maggior parte dei programmatori è muta quando gli altri programmatori chiedono aiuto perché non sono autorizzati a usare il codice open source e poi commentano su come sia facile installare il codice e usarlo. Ci sono ancora aziende che non permettono ai loro programmatori di usare il codice esterno a meno che non vengano sottoposti a rigorosi test per funzionalità, prestazioni, sicurezza, ecc. La mia compagnia sembra essere proprio così. Preferiscono che si reinventhi la ruota piuttosto che usare il codice esterno e fare tutto il possibile per impedirne l'uso. –

risposta

0

Se si dispone dell'impostazione delle chiavi dell'host ssh, è sufficiente eseguire il comando ssh system e successivamente specificare il comando da eseguire sulla macchina. Ad esempio:

`ssh [email protected] id` 

Dovresti riuscire a masticare/memorizzare quell'output.

7

È sempre possibile installare i moduli localmente, e questo è il metodo da controllare; tuttavia, si dovrebbe essere in grado di cavarsela con

#!/usr/bin/perl 

use strict; 
use warnings; 

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

chomp $id; 

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

Supponendo che sei in un ambiente come me in cui non è possibile aggiungere moduli aggiuntivi e non è possibile creare un file di identità, allora è possibile utilizzare questo sceneggiatura come punto di partenza.

Se è possibile impostare le chiavi SSH quindi è sufficiente utilizzare il comando backticks già postato, anche se potrebbe essere necessario l'opzione -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

Expect non è un modulo standard ... – lbalazscs

13

Il modo migliore per eseguire comandi da remoto tramite SSH è

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

Puoi usare questo in bash o in perl. Tuttavia, se si desidera utilizzare perl, è possibile installare i moduli perl nel proprio percorso di directory locale come suggerito da brian nel suo commento o dalle FAQ Perl al numero "How do I keep my own module/library directory?". Invece di utilizzare Net :: SSH, suggerirei di utilizzare Net :: SSH :: Perl con l'esempio seguente.

#!/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: Qualche aggiornamento su questo? – Space

1

Se si sta utilizzando backticks provare questo:

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

print "output: @output"; 

Questo è utile solo se si dispone di una chiave pubblica che il comando di cui sopra non chiederà la password.

2

o, assumendo chiavi di host sono presenti e si vuole fare qualcosa con il comando ouput ...

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

ho avuto un problema simile, e dopo molte ricerche ho trovato un semplice opzione. Ho usato qx() e ho eseguito i comandi ssh come avrei fatto normalmente. Il problema è che dovevo catturare sia stderr che stdout.

Quanto segue è un esempio di quello che ho usato:

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

Si corre il comando python -V, il quale emette le informazioni sulla versione per stderr. In questo esempio, il mio indirizzo IP è stato memorizzato nella variabile $curIP. Infine, lo 2>&1 aiuta a catturare sia stdout che stderr. Non ho specificato una password, in quanto ho configurato la chiave di scambio. Spero che questo ti aiuti.

0

So che questo è un thread molto vecchio, ma poiché ho incontrato lo stesso problema ho trovato un'altra soluzione utile nel caso in cui qualcuno stia 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' 
     ]; 

Si presume che siano stati configurati tasti ssh, quindi non sarà richiesto alcun input da parte dell'utente. Non volevo avere valori codificati, questo è il modo migliore per me che ha funzionato al meglio. Sto usando readpipe per raggiungere questo obiettivo.

Spero che questo aiuti ad avere una soluzione in caso di non hard coding.

Problemi correlati