本例子尝试使用Perl脚本借助Expect模块实现如下目的:

  • 登陆多台设备

设备登陆信息按如下格式存放于文件中。

$ cat hosts.txt
192.168.30.7:node1:telnet:bee1:123456
192.168.30.66:node2:ssh:bee2:123456
  • 在每台设备上批量执行命令

要执行的命令集合按如下格式存放于文件中。

$ cat cmds.txt
date
w
ifconfig
more mylog.txt
  • Perl脚本实现,使用了Expect模块

借助Expect模块实现登陆,执行命令,捕获命令回显,取日志,自动回复more分页,ping探测主机等功能。

脚本中的语句形式可供参考。

  • 脚本如下:
#! /usr/bin/perl

#安装模块
#cpan
#install Expect
#install Net::Ping
#perl -MCPAN -e "install autodie" use utf8;
use Expect;
use autodie;
use Net::Ping; #0为关闭本地回显
#$Expect::Log_Stdout=0;
$ENV{TERM}="xterm";
#不进行缓冲直接进文件
#$|=1; #cmds.txt的文件格式:
#一行一条命令
my @cmds;
my $cmds_file="./cmds.txt";
open CMDS,"<",$cmds_file or die "Can't open file $cmds_file: $!\n";
print "commands to run: \n";
while(<CMDS>){
print "$_";
chomp;
push @cmds,$_;
}
close CMDS;
print "=============================\n"; mkdir 'log' unless -e 'log';
chomp(my $now=`date +%y%m%d`);
my $exp=Expect->new;
#$exp->raw_pty(1); #hosts.txt的文件格式:
#IPv4地址:主机名:登陆方式(ssh/telnet):用户名:密码
my $hosts_file="./hosts.txt";
open HOSTS,"<",$hosts_file or die "Can't open file $hosts_file: $!\n";
while(<HOSTS>){
chomp;
@host=split /:/;
if(&ping_host(@host)){
&login_host(@host);
}
}
close HOSTS;
print "Loging finished!\n"; #子程序
sub login_host{
print "login to $_[1]($_[0])...\n";
my $user=$_[3];
my $passwd=$_[4];
my $ahost=$_[1]; if($_[2] =~ /ssh/i){
$exp=Expect->spawn("ssh -l $user $_[0]") or die "Can't login to $_[1]($_[0]): $!\n";
$exp->expect(3,
[ #使用正则来表达包含关系
qr/connecting\s\(yes\/no\)\?/i,
sub {
my $self=shift;
$self->send("yes\n");
exp_continue;
}
],
[
qr/password:/i,
sub {
my $self=shift;
$self->send("$passwd\n");
exp_continue_timeout;
}
]
);
#取log
$exp->log_file("log/$_[1]-$now.log", "w");
$exp->send("\n"); foreach (@cmds){
$exp->send("$_\n");
$exp->expect(2,
[ #使用正则来表达包含关系
qr/\[>#$\]/,
sub {
my $self=shift;
$self->send("\n");
exp_continue_timeout;
}
],
[
qr/--More--/i,
sub {
my $self=shift;
$self->send(" ");
exp_continue;
}
]
);
}
#关闭log
$exp->log_file(undef);
#退出登陆
$exp->send("exit\n") if ($exp->expect(undef,'-re' => '[>#$]')); #undef是痴等
print "\nLogout from $_[1]($_[0])\n";
}else{
$exp=Expect->spawn("telnet $_[0]") or die "Can't login to $_[1]($_[0]): $!\n";
$exp->expect(30,
[ #使用正则来表达包含关系,否则就是精确匹配
qr/$ahost login:/i,
sub {
my $self=shift;
$self->send("$user\n");
exp_continue;
}
],
[
qr/Password:/i,
sub {
my $self=shift;
$self->send("$passwd\n");
exp_continue_timeout;
}
]
);
#取log
$exp->log_file("log/$_[1]-$now.log", "w");
$exp->send("\n"); foreach (@cmds){
$exp->send("$_\n");
$exp->expect(2,
[ #使用正则来表达包含关系,否则就是精确匹配
qr/\[>#$\]/,
sub {
my $self=shift;
$self->send("\n");
exp_continue_timeout;
}
],
[
qr/--More--/i,
sub {
my $self=shift;
$self->send(" ");
exp_continue;
}
]
);
}
#关闭log
$exp->log_file(undef);
#退出登陆
$exp->send("exit\n") if ($exp->expect(undef,'-re' => '[>#$]')); #undef是痴等
print "\nLogout from $_[1]($_[0])\n";
}
} sub ping_host{
$p=Net::Ping->new("icmp");
if($p->ping($_[0])){
print "$_[1]($_[0]) is alive\n";
return 1;
}else{
print "$_[1]($_[0]) is die\n";
return 0;
}
}

Perl脚本通过Expect登陆多台设备批量执行命令并Log的更多相关文章

  1. 【Shell实战】批量在多台服务器上执行命令

    功能说明:批量在多台服务器上执行命令 #!/bin/bash # ========================================== # 功能:批量在多台服务器上执行命令 # 方法: ...

  2. shell脚本批量执行命令----必需判断上一步执行结果--没有捷径

    # 注意:shell脚本批量执行命令,不能只写一个函数,然后把所有命令复制进去,之前试过这样是不行的.必须要有一个判断命令执行成功与否的语句 # 简单的命令可以不加结果判断符号,但是遇到解压包.sed ...

  3. expect 批量执行命令

    在跳板机上执行脚本,登录到远程机器分区格式化挂载命令 #!/bin/bashpasswd='engine'/usr/bin/expect <<-EOFset time 40spawn ss ...

  4. windows 批量执行命令的脚本

    因为老板一个电话,我的国庆节就没了....,老板要我写个东西,能批量执行500台windows的命令并返回结果,虽然完成以后是非常的简单,但是因为我走了很多弯路,一开始想用powershell来写,后 ...

  5. python实现Telnet远程登陆到设备并执行命令

    #encoding=utf-8 import telnetlib import time def do_telnet(Host, username, password, finish, command ...

  6. shell 脚本实战笔记(8)--ssh免密码输入执行命令

    前言: ssh命令, 没有指定密码的参数. 以至于在脚本中使用ssh命令的时候, 必须手动输入密码, 才能继续执行. 这样使得脚本的自动化执行变得很差, 尤其当ssh对应的机器数很多的时候, 会令人抓 ...

  7. shell脚本安装python、pip-----非交互式的--批量执行函数

    首先把pip-.tgz 安装包放在 /usr/local 下面,按照顺序先安装pip,再安装python.不要先安装或只安装python,否则很容易出错, cat >>pip-python ...

  8. CentOS 下运维自动化 Shell 脚本之 expect

    CentOS 下运维自动化 Shell脚本之expect 一.预备知识: 1.在 Terminal 中反斜杠,即 "" 代表转义符,或称逃脱符.("echo -e与pri ...

  9. linux集群自动化搭建(生成密钥对+分发公钥+远程批量执行脚本)

    之前介绍过ansible的使用,通过ssh授权批量控制服务器集群 但是生成密钥和分发公钥的时候都是需要确认密码的,这一步也是可以自动化的,利用ssh + expect + scp就可以实现,其实只用这 ...

随机推荐

  1. ecshop 除去版权信息

    ECSHOP 2.73彻底去版权的方法 前台部分: 1. 去掉头部TITLE “- Powered by ecshop” 后者打开includes/lib_main.php $page_title = ...

  2. Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO)

    本文转载 https://www.javadoop.com 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.c ...

  3. hibernate class cast exception from object to ...

    http://stackoverflow.com/questions/22548325/java-lang-classcastexception-cannot-be-cast-to-java-lang ...

  4. postgresql获取表最后更新时间(通过表磁盘存储文件时间)

    一.创建获取表更新时间的函数 --获取表记录更新时间(通过表磁盘存储文件时间) create or replace function table_file_access_info( IN schema ...

  5. Flask中的实例化配置

    也就是在app=Flask(__name__)括号中的参数 1.static_folder = 'static', # 静态文件目录的路径 默认当前项目中的static目录 2.static_url_ ...

  6. ThreadPoolExecutor 源码分析

    ThreadPoolExecutor 线程池核心实现类 线程池的生命周期 RUNNING: 接受新任务,同时处理工作队列中的任务 SHUTDOWN: 不接受新任务,但是能处理工作队列中的任务 STOP ...

  7. centos修改时区,同步时间

    查看当前系统时区 ls -la /etc/localtime 查看支持的时区 timedatectl list-timezones # 查看所有时区 timedatectl list-timezone ...

  8. SpringBoot系列:二、SpringBoot的配置文件

    SpringBoot的配置文件在resources文件夹下 springboot的配置文件支持两种形式的写法,一种是经典的properties另一种是yml yml通过空格缩进的形式来表示对象的层级关 ...

  9. TensorFlow学习笔记6-数值计算基础

    TensorFlow学习笔记6-数值计算 本笔记内容为"数值计算的基础知识".内容主要参考<Deep Learning>中文版. \(X\)表示训练集的矩阵,其大小为m ...

  10. Leveldb源码分析--2

    coming from http://blog.csdn.net/sparkliang/article/details/8573618