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还是很多)

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

  • 相关阅读:
    React.Fragment
    微信分享
    视频H5 video标签最佳实践
    详解vue2.0+vue-video-player实现hls播放全过程
    call()和appl()的理解
    JS 原生面经从初级到高级
    vue面试
    面试题2
    IdentityServer4 实现 OpenID Connect 和 OAuth 2.0
    DDD关键知识点整理汇总
  • 原文地址:https://www.cnblogs.com/pigdragon/p/6473290.html
Copyright © 2011-2022 走看看