2010-05-17 3 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.