Je veux SSH sur un serveur et exécuter une commande simple comme "id" et obtenir la sortie de celle-ci et la stocker dans un fichier sur mon serveur principal. Je n'ai pas de privilèges pour installer Net :: SSH , ce qui me faciliterait grandement la tâche. S'il vous plaît me fournir une solution pour cela. J'ai essayé d'utiliser back-ticks mais je ne suis pas en mesure de stocker la sortie sur la machine à partir de laquelle mon script est exécuté.
Le meilleur moyen d'exécuter des commandes à distance à l'aide de SSH est
$ ssh user@Host "command" > output.file
Vous pouvez l'utiliser soit en bash, soit en Perl. Toutefois, si vous souhaitez utiliser Perl, vous pouvez installer les modules Perl dans votre chemin de répertoire local, comme suggéré par brian dans son commentaire ou depuis Perl FAQ à " Comment puis-je conserver mon propre répertoire module/library? ". Au lieu d'utiliser Net :: SSH, je suggérerais d'utiliser Net :: SSH :: Perl avec l'exemple ci-dessous.
#!/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;
Vous pouvez toujours installer des modules localement, et c'est la méthode que vous devriez examiner. cependant, vous devriez pouvoir vous en tirer
#!/usr/bin/Perl
use strict;
use warnings;
my $id = qx/ssh remotehost id 2>&1/;
chomp $id;
print "id is [$id]\n"
ou bien, en supposant que les clés de l'hôte sont présentes et que vous voulez faire quelque chose avec la commande ouput ...
open(SSH,"/usr/bin/ssh you\@server ps aux |") or die "$!\n";
while (<SSH>) {
# do stuff with $_
}
close SSH;
J'ai eu un problème similaire, et après beaucoup de recherches, j'ai trouvé une option simple. J'ai utilisé qx()
et exécuté les commandes ssh comme je le ferais normalement. Le piège est que je devais capturer stderr et stdout.
Voici un exemple de ce que j'ai utilisé:
my $output = qx(ssh root\@$curIP python -V 2>&1);
Il exécute la commande python -V
, qui renvoie les informations de version sur stderr
. Dans cet exemple, mon adresse IP était stockée dans la variable $curIP
. Enfin, le 2>&1
permet de capturer à la fois stdout et stderr. Je n'ai pas spécifié de mot de passe car j'ai la configuration des échanges de clés. J'espère que cela t'aides.
Si vous utilisez des backticks, essayez ceci:
my @output = `ssh [email protected] "which Perl"`;
print "output: @output";
Ceci n'est utile que si vous avez un publickey que la commande ci-dessus ne demande pas de mot de passe.
En supposant que vous vous trouvez dans un environnement comme moi où vous ne pouvez pas ajouter de modules supplémentaires ni créer de fichier d'identité, vous pouvez utiliser ce script comme point de départ.
Si vous pouvez configurer des clés ssh, utilisez simplement la commande backticks déjà publiée, bien que vous ayez peut-être besoin de l'option -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();
Je sais que c'est un très vieux sujet, mais depuis que je rencontre le même problème, j'ai trouvé une autre solution utile dans le cas où quelqu'un utilise 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'
];
Cela suppose que vous avez configuré les clés ssh afin qu'aucune entrée de l'utilisateur ne soit requise. Je ne voulais pas avoir de valeurs codées en dur, c’est la meilleure façon pour moi de donner les meilleurs résultats. J'utilise readpipe pour y parvenir.
J'espère que cela aide à avoir une solution en cas de codage difficile.
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
}
}
Si vous avez configuré les clés d’hôte ssh, vous pouvez simplement exécuter la commande système ssh puis spécifier celle à exécuter sur la machine. Par exemple:
`ssh [email protected] id`
Vous devriez être capable de chomp/stocker cette sortie.