#!/usr/bin/env perl use threads; use threads::shared qw[ shared_clone ]; use v5.14.2; use strict; use Data::Dump qw(dd pp); my (@hosts) = split /,/, shift @ARGV || usage('Missing host[,host2,...]'); say "num hosts: " . scalar(@hosts); my $user = shift(@ARGV) || usage('Missing user'); my $pass = shift(@ARGV) || usage('Missing password'); my $port = 22; my @ssh2_handles : shared; sub opener { use Net::SSH2; my ( $idx, $host ) = @_; say "$idx, $host"; my $ssh2 = Net::SSH2->new( trace => -1 ); lock @ssh2_handles; $ssh2_handles[$idx] = shared_clone($ssh2); return; } my $idx = 0; # my @openers = async( \&opener, $idx++, $_ ) for @hosts; # this creates zero elements my @openers; push @openers, async( \&opener, $idx++, $_ ) for @hosts; say "num openers created: " . scalar(@openers); $_->join for @openers; say "openers completed"; my $host = $hosts[0]; my $ssh2_handle = $ssh2_handles[0]; say "dump of ssh2_handle:"; dd $ssh2_handle; say 'dump of $ssh2_handles[0]:'; dd $ssh2_handles[0]; my $ok; eval { say "Trying to connect to $host"; $ok = $ssh2_handle->connect( $host, $port ); }; die "Whoops: $@" if $@; die "SSH unable to connect for some reason" unless $ok; say "Connected to '$host'"; $ssh2_handle->auth_password( $user, $pass ) // $ssh2_handle->auth_password( $user, $pass ) // die "ERROR: Failed to authenticate"; say "Authenticated as user '$user'"; sub usage { my ($msg) = @_; say STDERR "FATAL: $msg" if $msg; say STDERR "Usage: $0 host[,host2,...] user password"; exit(1); }