Linux命令(27):shell 结合expect,多服务器批量分发数据
在部署一个任务时,其中有一项必须的过程就是将一些文件,如安装包发送到大量的服务器上去。虽然已有宇哥的脚本可用:通过paramiko模块提供的ssh和scp功能编写的python脚本。但我到现在还在对python的恐惧之中(虽然已经在空闲时间努力去学习了),所以使用了shell和expect脚本结合的方式,写了这个批量scp的脚本工具。
expect用于自动化地执行linux环境下的命令行交互任务,例如scp、ssh之类需要用户手动输入密码然后确认的任务。有了这个工具,定义在scp过程中可能遇到的情况,然后编写相应的处理语句,就可以自动地完成scp操作了。
需要expect工具的话可以在linux环境中使用apt-get或pacman这些包管理工具去获取安装,或是到expect开源项目的网站:http://expect.sourceforge.net/ 来获取。
安装expect之后,可以尝试使用以下的代码来完成对单个服务器的scp任务:
#!/usr/bin/expect
set timeout
set host [lindex $argv ]
set username [lindex $argv ]
set password [lindex $argv ]
set src_file [lindex $argv ]
set dest_file [lindex $argv ]
spawn scp -r $src_file $username@$host:$dest_file #add -r cam move dir
expect {
"(yes/no)?"
{
send "yes\n"
expect "*assword:" { send "$password\n"}
}
"*assword:"
{
send "$password\n"
}
}
expect "100%"
expect eof
注意代码刚开始的第一行,指定了expect的路径,与shell脚本相同,这一句指定了程序在执行时到哪里去寻找相应的启动程序。代码刚开始还设定了timeout的时间为10秒,如果在执行scp任务时遇到了代码中没有指定的异常,则在等待10秒后该脚本的执行会自动终止。
从以上代码刚开始的几行可以看出,我为这个脚本设置了5个需要手动输入的参数,分别为:目标主机的IP、用户名、密码、本地文件路径、目标主机中的文件路径。如果将以上脚本保存为expect_scp文件,则在shell下执行时需要按以下的规范来输入命令:
./expect_scp 192.168.75.130 root 123456 /root/src_file /root/dest_file
以上的命令执行后,将把本地/root目录下的src_file文件拷贝到用户名为root,密码为123456的主机192.168.75.130中的/root下,同时还将这个源文件重命名为dest_file。
spawn代表在本地终端执行的语句,在该语句开始执行后,expect开始捕获终端的输出信息,然后做出对应的操作。expect代码中的捕获的(yes/no)内容用于完成第一次访问目标主机时保存密钥的操作。有了这一句,scp的任务减少了中断的情况。代码结尾的expect eof与spawn对应,表示捕获终端输出信息的终止。
有了这段expect的代码,还只能完成对单个远程主机的scp任务。如果需要实现批量scp的任务,则需要再写一个shell脚本来调用这个expect脚本。
shell脚本:
#!/bin/sh
list_file=$
src_file=$
dest_file=$
cat $list_file | while read line
do
host_ip=`echo $line | awk '{print $1}'`
username=`echo $line | awk '{print $2}'`
password=`echo $line | awk '{print $3}'`
echo "$host_ip"
./expect_scp $host_ip $username $password $src_file $dest_file
done
指定了3个参数:列表文件的位置、本地源文件路径、远程主机目标文件路径。需要说明的是其中的列表文件指定了远程主机ip、用户名、密码,这些信息需要写成以下的格式:
IP username password
中间用空格或tab键来分隔,多台主机的信息需要写多行内容,如:
192.168.75.130 root 123456
192.168.75.131 knktc testpass
这样就指定了两台远程主机的信息。注意,如果远程主机密码中有“$”、“#”这类特殊字符的话,在编写列表文件时就需要在这些特殊字符前加上转义字符,否则expect在执行时会输入错误的密码。
对于这个shell脚本,保存为batch_scp.sh文件,与刚才保存的expect_scp文件和列表文件(就定义为hosts.list文件吧)放到同一目录下,执行时按照以下方式输入命令就可以了:
./batch_scp.sh ./hosts.list /root/src_file /root/destfile
or
sh batch_scp.sh hosts.list /root/src_file /root/destfile
hosts.list:服务器的列表
/root/src_file:需要分发的文件
/root/destfile:需要存储到目标服务器的地址
用这两个脚本文件,就可以简单地完成批量scp的任务了。
其实批量scp的任务并不难,但是批量ssh的任务可能就会遇到麻烦了。
Linux命令(27):shell 结合expect,多服务器批量分发数据的更多相关文章
- 常用linux命令及shell脚本
参考:Linux命令大全 分割大文件 Split命令 按行分割(只能是文本文件) $split -l 1000 big_file 前缀 按文件大小分割 $split -b 64m big_file 前 ...
- Java执行cmd命令、bat脚本、linux命令,shell脚本等
1.Windows下执行cmd命令 如复制 D:\tmp\my.txt 到D:\tmp\my_by_only_cmd.txt 现文件如图示: 执行代码: private static void run ...
- 如何在java程序中调用linux命令或者shell脚本
转自:http://blog.sina.com.cn/s/blog_6433391301019bpn.html 在java程序中如何调用linux的命令?如何调用shell脚本呢? 这里不得不提到ja ...
- SSH Secure Shell Client连接Linux 命令行显示中文乱码问题 和oracle 查询数据中文乱码问题
一.SSH Secure Shell Client连接Linux 命令行显示中文乱码问题 linux 设置系统语言 修改 /etc/sysconfig/i18n 文件,如 LANG="en_ ...
- linux命令行模式下对FTP服务器进行文件上传下载
参考源:点击这里查看 1. 连接ftp服务器 格式:ftp [hostname| ip-address]a)在linux命令行下输入: ftp 192.168.1.1 b)服务器询问你用户名和密码 ...
- Linux命令行和shell编程
Shell Shell是一个程序,用户输入的命令通过shell来传达给内核或其它程序.用户在linux打开一个终端,终端就会自动调用用户的shell. Linux上的Shell有很多种,用的最多是sh ...
- shell编程-ssh免交互批量分发公钥脚本
脚本基本原理 1.控制端免交互创建秘钥和公钥: 1 ssh-keygen -t rsa -f /root/.ssh/id_rsa -N "" 2.免交互发送公钥 1 sshpass ...
- Linux命令与Shell
Linux 目录结构及解释 查看命令行执行完位置: echo $BASH 命令记录 mkdir mkdir命令 用来创建目录. 语法:mkdir (选项)(参数) 主要选项: -m<目标属性& ...
- 每天一个linux命令(27)--tar命令
通过SSH访问服务器,难免会要用到压缩,解压缩,打包,解包等,这时候 tar 命令就是必不可少的一个功能强大的工具.Linux 中最流行的 tar 是麻雀虽小,五脏俱全. tar 命令可以为Linux ...
随机推荐
- Oracle的REGEXP_SUBSTR函数简单使用方法
REGEXP_SUBSTR延伸SUBSTR函数的功能.让你搜索一个正則表達式模式字符串. 这也相似于REGEXP_INSTR.而是返回子字符串的位置,它返回的子字符串本身. 语法 Oracle数据库中 ...
- mixin
mixin.scss //-----------------------------------浏览器前缀----------------------------------------- //例子: ...
- info.plist
更新了Xcode8 以及 iOS10,App访问用户的相机.相册.麦克风.通讯录的权限都需要重新进行相关的配置,不然在Xcode8中打开编译的话会直接crash. 需要在info.plist中添加Ap ...
- 实战c++中的vector系列--将迭代器转换为索引
stl的迭代器非常方便 用于各种算法. 可是一想到vector.我们总是把他当做数组,总喜欢使用下标索引,而不是迭代器. 这里有个问题就是怎样把迭代器转换为索引: #include <vecto ...
- HTTP Header具体解释
HTTP(HyperTextTransferProtocol) 即超文本传输协议,眼下网页传输的的通用协议.HTTP协议採用了请求/响应模型,浏览器或其它client发出请求.server给与响应.就 ...
- [TODO]com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method
异常信息如下: 2018-10-30 20:00:50.230 ERROR java.util.concurrent.ExecutionException: com.alibaba.dubbo.rpc ...
- java 和 C 代码运行效率的比较(整理)
最近和朋友无意间讨论起了 有关java 和C 的 效率问题, (我是java 推介者, 他是 c 语言推介者, 他做的是嵌入式) 故,想通过网络查询一下, 总结一下,两者到底效率如何,其有何差异,原因 ...
- Drupal Form问题汇总
问:如何校验和提交表单?答:Drupal允许定义默认的表单校验处理函数和提交处理函数. function practice_demo_form($form, &$form_state) { . ...
- 微信小程序用户数据解密
概述 通过微信web开发者工具创建登录,获取用户信息,发送至后台,进行用户数据解密 详细 代码下载:http://www.demodashi.com/demo/10705.html 一.准备工作 1. ...
- 【微信小程序】:评论、回复和删除功能 -- 2017/7/14
1.理论核心:传参->pid,评论父id需要在wxml页面传递:小程序端和WEB端不同核心:前者操纵数据,后者操纵DOM元素对象 2.不废话,直接代码:wxml <view class=& ...