expect用于自动化地执行linux环境下的命令行交互任务,例如scp、ssh之类需要用户手动输入密码然后确认的任务。有了这个工具,定义在scp过程中可能遇到的情况,然后编写相应的处理语句,就可以自动地完成scp操作了。
需要expect工具的话可以在linux环境中使用apt-get或yun install expect去获取安装,或是到expect开源项目的网站:http://expect.sourceforge.net/ 来获取。
安装expect之后,可以尝试使用以下的代码来完成对单个服务器的scp任务:
#!/usr/bin/expect set timeout 30 set host [lindex $argv 0] set port [lindex $argv 1] set username [lindex $argv 2] set password [lindex $argv 3] set src_file [lindex $argv 4] set dest_file [lindex $argv 5] spawn scp -P $port $src_file $username@$host:$dest_file expect { "(yes/no)?" { send "yes\n" expect "*assword: " { send "$password\n"} } "*assword: " { send "$password\n" } } expect "100%" expect eof
注意代码刚开始的第一行,指定了expect的路径,与shell脚本相同,这一句指定了程序在执行时到哪里去寻找相应的启动程序。代码刚开始还设定了timeout的时间为30秒,如果在执行scp任务时遇到了代码中没有指定的异常,则在等待30秒后该脚本的执行会自动终止。
从以上代码刚开始的几行可以看出,我为这个脚本设置了6个需要手动输入的参数,分别为:目标主机的IP、ssh端口、用户名、密码、本地文件路径、目标主机中的文件路径。如果将以上脚本保存为expect_scp文件,则在shell下执行时需要按以下的规范来输入命令:
./expect_scp 192.168.1.10 22 root 123456 /root/src_file /root/dest_file
以上的命令执行后,将把本地/root目录下的src_file文件拷贝到用户名为root,密码为123456的主机192.168.1.10中的/root下,同时还将这个源文件重命名为dest_file。
spawn代表在本地终端执行的语句,在该语句开始执行后,expect开始捕获终端的输出信息,然后做出对应的操作。expect代码中的捕获的(yes/no)内容用于完成第一次访问目标主机时保存密钥的操作。有了这一句,scp的任务减少了中断的情况。代码结尾的expect eof与spawn对应,表示捕获终端输出信息的终止。
有了这段expect的代码,还只能完成对单个远程主机的scp任务。如果需要实现批量scp的任务,则需要再写一个shell脚本来调用这个expect脚本:
#!/bin/sh list_file=$1 src_file=$2 dest_file=$3 cat $list_file | while read line do host=`echo $line | awk '{print $1}'` port=`echo $line | awk '{print $2}'` username=`echo $line | awk '{print $3}'` password=`echo $line | awk '{print $4}'` echo "$host" ./expect_scp $host $port $username $password $src_file $dest_file done
指定了3个参数:列表文件的位置、本地源文件路径、远程主机目标文件路径。需要说明的是其中的列表文件指定了远程主机ip、ssh端口、用户名、密码,这些信息需要写成以下的格式:
host port username password
中间用空格或tab键来分隔,多台主机的信息需要写多行内容,如:
192.168.75.130 22 root 123456
192.168.75.131 10022 knktc testpass
这样就指定了两台远程主机的信息。注意,如果远程主机密码中有“$”、“#”这类特殊字符的话,在编写列表文件时就需要在这些特殊字符前加上转义字符,否则expect在执行时会输入错误的密码。
对于这个shell脚本,保存为batch_scp.sh文件,与刚才保存的expect_scp文件和列表文件(就定义为hosts.list文件吧)放到同一目录下,执行时按照以下方式输入命令就可以了:
./batch_scp.sh ./hosts.list /root/src_file /root/destfile
用这两个脚本文件,就可以简单地完成批量scp的任务了。
其实批量scp的任务并不难,但是批量ssh的任务可能就会遇到麻烦了。
相关推荐
linux使用shell脚本利用expect工具实现SCP传输文件到多台服务器
shell脚本无密码登录 expect的使用方法详解 今天需要做一个定时任务脚本将最新的数据包文件传到远程的服务器上,虽然有密钥但也是要求输入密码的那种,所以只能另想办法实现让脚本自动输入密码了。 从网上查到使用...
今天公司同事要在一台服务器上对另外两台同机房的服务器进行文件传输,两台服务器的文件存放地址一致,密码和key也一致(我们公司在安全上做得有点变态的),为了效率写了下面这个脚本. 1.单台传输脚本 cat /root/soft_...
通过A服务器自动登录其他服务器自动传输文件、删除文件、自动检测tomcat启动状态,控制启动和停止、可配置多条服务器进行同步处理,适合集群管理
批量远程操作脚本-- scp 和 ssh 无环境依赖,解压压缩包即可使用,较原生 expect 慢,可定制性高。 使用方法: 当前目录创建 ip list: 192.168.0.100 192.168.0.101 pscp.py 拷贝本地文件到远程机器(iplist.txt)...
一、遇到的问题 我们使用过mysqldump都知道... 创建一个utils文件,里面存放shell脚本,包括mysqldump、scp等命令 使用expect脚本,执行utils内的脚本,并为其自动输入密码 最后使用驱动脚本,执行expect,在该脚本里
参考expect4j的交互式操作方式控制输入输出流实现批量执行多条shell命令同时支持切换用户输入密码提权执行命令输入密码等操作 有完整的测试用例,便于理解 模板化执行命令示例 [$]send[su - root] [Password:]...
在java里可以通过Ganymed SSH-2, Expect4j等实现ssh登录,由于Ganymed SSH-2是纯java实现,并且可以实现scp,sftp等,因此我们采用Ganymed SSH-2 1> 下载安装 从http://code.google.com/p/ganymed-ssh-2/ 下载...
expect是一种自动交互语言,能实现在shell脚本中为scp和ssh等自动输入密码自动登录。下面这篇文章主要介绍了linux中使用expect的方法示例,需要的朋友可以参考借鉴,下面来一起学习学习吧。
该脚本由bash shell实现,功能类似expect,ssh到远程主机可以实现自动输入密码(密码验证模式下),用法比expect简单很多。 示例如下: $ ./autopass Usage: autopass -h host [-u user] [-p port] [-k password |...
首先确保每个节点已经安装了expect ,确保服务器/root/script路径存在 修改每个节点ssh配置 vi /etc/ssh/ssh_config ------------------------------- # StrictHostKeyChecking ask -----------------------------...