zoukankan      html  css  js  c++  java
  • Linux shell批量执行scp脚本工具

    转载: linux shell + expect:批量scp脚本工具             2011-09-13 15:51:06          

    分类: Python/Ruby

    最近在准备一个部署的任务,其中有一项必须的过程就是将一些文件,如安装包发送到大量的服务器上去。虽然已有宇哥的脚本可用:通过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任务:

     1: #!/usr/bin/expect

     2:

     3: set timeout 10

     4: set host [lindex $argv 0]

     5: set username [lindex $argv 1]

     6: set password [lindex $argv 2]

     7: set src_file [lindex $argv 3]

     8: set dest_file [lindex $argv 4]

     9:

     10: spawn scp $src_file $username@$host:$dest_file

     11: expect {

     12:     "(yes/no)?"

     13:         {

     14:             send "yes "

     15:             expect "*assword:" { send "$password "}

     16:         }

     17:     "*assword:"

     18:         {

     19:             send "$password "

     20:         }

     21:     }

     22: expect "100%"

     23: 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脚本内容如下:

     1: #!/bin/sh

     2:

     3: list_file=$1

     4: src_file=$2

     5: dest_file=$3

     6:

     7: cat $list_file | while read line

     8: do

     9:     host_ip=`echo $line | awk '{print $1}'`

     10:     username=`echo $line | awk '{print $2}'`

     11:     password=`echo $line | awk '{print $3}'`

     12:     echo "$host_ip"

     13:     ./expect_scp $host_ip $username $password $src_file $dest_file

     15: 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

    用这两个脚本文件,就可以简单地完成批量scp的任务了。

    其实批量scp的任务并不难,但是批量ssh的任务可能就会遇到麻烦了。批量ssh的功能正在学习中……(其实已经可以用了但是bug还是很多)

    希望这个脚本能够帮到大家,谢谢!

  • 相关阅读:
    SharePoint 2010 User Profile Sync Service自动停止
    如何区别多个svchost.exe?
    Log Parser分析IIS log的一个简单例子
    Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
    Windows中右键点击文件夹, 结果找不到共享选项卡, 怎么办?
    介绍SOS中的SaveModule命令
    SharePoint中Draft版本的文档不会收到document added的Alert Email
    和我一起学Windows Workflow Foundation(1)创建和调试一个WF实例
    门户网站
    C#基础—— check、lock、using语句归纳
  • 原文地址:https://www.cnblogs.com/pigdragon/p/6473290.html
Copyright © 2011-2022 走看看