ssh_pbs.pl for LSF batch systems
#!/usr/bin/perl
#
# A program to run a command via ssh on the set of nodes in an LSF job
#
use English;
use Getopt::Long;
&Getopt::Long::Configure( 'noignorecase', 'no_autoabbrev');
$stat = Getopt::Long::GetOptions(
'help|h' => \$print_help,
'skip=s' => \$opt_s,
'n=s' => \$opt_n
);
# Don't continue if there are any unknown options on command line
if ($Getopt::Long::error != 0)
{
exit;
}
if (defined($print_help))
{
print STDERR <
ssh to only the first N nodes of the job
-skip
ssh to every Mth node [including the first] in the job
This will ssh to every Mth node of the first N nodes when combined
with the -n option.
MYEOF
exit;
}
$myargc= scalar(@ARGV);
if ($myargc < 2)
{
print "usage: $PROGRAM_NAME [OPTIONS] pbs_jobid \"/some/command1; /another/command2\"\n";
exit;
}
#LSF
$bjobs=`/usr/local/bin_first/bjobs -l $ARGV[0]`;
if ($bjobs =~ /Job.*?is not found/)
{
$bjobs=`bhist -n8 -l $ARGV[0]`;
}
($junk,$nodes)= split /Started on.*?Hosts\SProcessors|Dispatched to.*?Hosts\SPro
cessors/, $bjobs;
($nodes,$junk)=split /Execution/, $nodes;
# clear away newlines
$nodes =~ s/\n//g;
# clear away extra spaces
$nodes =~ s/\s//g;
(@nodes)= split /\*/, $nodes;
foreach $n (@nodes)
{
if ($n =~ /tun.*/)
{
($node, $junk)= split />/, $n;
$node =~ s/\s//g;
chomp $node;
push @nodelist, ($node);
}
}
@nodes= @nodelist;
$prev_node="";
$nodecount=0;
$skipcount=0;
foreach $node (@nodes)
{
($node)= split/\//, $node;
if (!($prev_node =~ /$node/))
{
# for -skip opt, only ssh when $skipcount is divisible by $opt_s
#
# when -skip=M and -n=N are combined, this will skip stride M
# through the first N nodes
if (defined($opt_s))
{
if (($skipcount % $opt_s) == 0)
{
$output=`ssh -q -x $node $ARGV[1]`;
print "$node: $output";
}
$skipcount++;
}
else
{
$output=`ssh -q -x $node $ARGV[1]`;
print "$node: $output";
}
# for -n opt, just ssh to the 1st $opt_n nodes, then exit
if (defined($opt_n))
{
$nodecount++;
if ($nodecount >= $opt_n)
{
exit;
}
}
}
$prev_node= $node;
}