zoukankan      html  css  js  c++  java
  • 转 在shell脚本中使用expect实现scp传输问题

    1.安装expect

    expect用于shell脚本中自动交互,其是基于tcl编程语言的工具。所以安装expect首先安装tcl。本文中使用的是expect5.45tcl8.6.6

    安装tcl

    [root@tseg0 /]$ mkdir /tools
    [root@tseg0 /]$ tar -zxvf tcl8.6.6-src.tar.gz
    [root@tseg0 /]$ cd tcl8.6.6/unix/
    [root@tseg0 /]$ ./configure
    [root@tseg0 /]$ make
    [root@tseg0 /]$ make install
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    安装expect

    [root@tseg0 /]$ cd /tools
    [root@tseg0 /]$ tar -zxvf expect5.45.tar.gz
    [root@tseg0 /]$ cd expect5.45/
    [root@tseg0 /]$ ./configure --with-tcl=/usr/local/lib/ --with-tcl include=/tools/tcl8.6.6/generic/
    [root@tseg0 /]$ make
    [root@tseg0 /]$ make install
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    shell脚本实现scp传输

    命令解释

    -c 表示可以在命令行下执行except脚本; 
    spawn 命令激活一个unix程序来交互,就是在之后要执行的命令; 
    expect “aaa” 表示程序在等待这个aaa的字符串; 
    send 向程序发送字符串,expect和send经常是成对出现的,比如当expect“aaa”的时候,send“bbb”。

    执行脚本

    #! /bin/sh
    expect -c "
        spawn scp -r /home/tseg/hello $name@10.103.240.33:/home/$name/
        expect {
            "*assword" {set timeout 300; send "$pass
    "; exp_continue;}
            "yes/no" {send "yes
    ";}
        }
    expect eof"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    解释: 
    第二行: -c 表示可以不用与控制台交互; 
    第三行:spawn激活一个scp的unix程序; 
    第五行:expect期待含有“assword”的字符串,设置连接时间最大为300毫秒,如果出现这个字符串,就send 变量pass代表的密码字符串, exp_continue表示执行下面的匹配; 
    第六航:expect期待含有“assword”的字符串,设置连接时间最大为300毫秒,如果出现这个字符串,就send 变量pass代表的密码字符串; 
    第八行:表示结束。

    ####sample 1:

    1.vi 1.sh

    #! /bin/sh

    export pass=123456
    export name=root
    expect -c " spawn scp -r /home/tseg/hello $name@10.103.240.33:/home/$name/ expect { "*assword" {set timeout -1; send "$pass "; exp_continue;} "yes/no" {send "yes ";} } expect eof"



    set timeout -1   ------->>>>>>注意此处的-1,-1表示永不超时,也就是:等 scp 命令正常执行完成之后,控制权会转移到下一行。  

    set timeout 300  ------->>>>>>300表示300秒后超时,在超时之后,控制权会转移到下一行;若在超时时间之内,程序运行完,则控制权也会转移到下一行。  




    2. nohup sh 1.sh


    转自 http://blog.csdn.net/BlockheadLS/article/details/52980797

    ####sampe 2

    感谢https://www.jianshu.com/p/71e9c9a9c31f

    shell 脚本sftp 文件下载

    Mr_Alfred
    2019.04.01 15:24:46字数 0阅读 1,454
    #!/bin/bash
    sftp_Host="192.168.1.1"
    sftp_userName="admin"
    sftp_passWord="admin"
    sftp_port=22
    sftpRemotePath="/data/fiels"
    sftpLocalPath="/root/sftp"
    current=$(date "+%Y-%m-%d %H:%M:%S")
    
    echo "当前时间是:$current"
    
    if [[ $# == 0 ]]; then
        yesterday=$(date "+%Y%m%d" -d "-1 days")
    fi
    if [[ $# == 1 ]]; then
        yesterday=$1
    fi
    myDir=$sftpLocalPath
    if [[ ! -d $myDir ]]; then
        mkdir -p $myDir
    fi
    sftpLoadPath=$sftpRemotePath$yesterday
    fileFilter=$yesterday*.gz
    
    # SFTP非交互式操作
    sftp_download()
    {
        expect <<- EOF
        set timeout 5
        spawn sftp  -P $sftp_port $sftp_userName@$sftp_Host
    
        expect { 
            "(yes/no)?" {send "yes
    "; expect_continue }
            "*assword:" {send "$sftp_passWord
    "}
        }
        expect "sftp>"
        send "cd $sftpLoadPath 
    "
        expect "sftp>"
        send "lcd $myDir 
    "
        expect "sftp>"
        set timeout -1
        send "mget $fileFilter 
    "
        expect "sftp>"
        send "bye
    "
    EOF
    }
    
    unGzipFiles(){
        cd $myDir
        fileList=`ls *`
        fileArr=($fileList)
        for fileName in ${fileArr[@]}
        do
            echo "开始解压文件:$fileName"
            gzip -d  $fileName
        done
    
    }
    
    reNameFiles(){
        cd $myDir
        fileList=`ls *`
        fileArr=($fileList)
    
        for fileName in ${fileArr[@]}
        do
            echo "reNameFile :$fileName"
            mv $fileName $fileName".csv"
        done  
    }
    
    echo "执行sftp下载操作 : 数据日期:$yesterday"
    sftp_download
    echo "$yesterday 文件下载完成"
    echo "执行解压操作"
    unGzipFiles
    echo "重命名文件"
    reNameFiles
    

     

    ########感谢 

    linux expect中的timeout设定

    在做日志分析工具时,发现在屏幕上拿到日志结果会有点慢,然后查了一下expect ssh timeout的设置,原来是这里有个默认时间的问题,所以整理一下:

    expect脚本我们都知道,首先spawn我们要执行的命令,然后就给出一堆expect的屏幕输出,如果输出match了我们的expect的东西,我们就会send一个命令上去,模拟用户输入。

    但是expect中等待命令的输出信息是有一个timeout的设定的,默认是10秒。这个特性是防止那些执行死机的命令的。一旦到了这个timeout,还是没有屏幕输出的话,expect脚本中下面的代码就会执行。或者我们在expect脚本中如果定义了timeout的响应代码的话,这些代码就会被执行。 

    解决这样的问题非常简单,最简单的办法就是在expect脚本的开头定义: 

    set timeout -1 -- 没有timeout set timeout XX -- 设定具体的timeout时间(秒)

    ###sample 

    感谢吴老师

    expect交互式安装软件
    公司一些宿主机需要安装软件,吴老师要求写一个安装脚本;

    脚本思路:首先要把安装的包拷贝到每台机器上,然后要让每台机器都运行一次安装命令;就想到了应用scp、ssh命令,但这两个命令需要输入对端密码,需要与机器交互;此时可以应用交互式命令expect。

    expect可以实现自动交互:

      set:设置变量;set timeout -1,永不超时;set timeout 300,300秒后没有expect内容出现退出;

      spawn:想要执行的命令,你想要进行的交互命令;

      expect:等待命令提示信息,交互的过程,系统会给一些输入密码等提示,expect就是抓取其中关键字,当expect抓取到了后面的关键字,就会执行send。

      send:发送信息,完成交互,检测到关键字后向交互界面输入的信息。

      interact:

      expect eof:结束退出;

    代码如下:


    #!/bin/bash
    #
    SERVERS="192.168.254.11 192.168.254.12 192.168.254.13"  //需要安装的所有主机
    PASSWORD="123456"  //统一密码
    VIB_FILE="/app/vmware-esx-MegaCli-8.07.07.vib"  //安装包路径
    SHELL_FILE="/app/megacli_install.sh"  //安装脚本(脚本中就一条安装vib文件的命令)

    vib_shell_copy(){
    expect << EOF
    set timeout -1  //设置超时时间
    spawn scp -o StrictHostKeyChecking=no $VIB_FILE $SHELL_FILE $1:/tmp/  //spawn调用scp命令将安装包和安装脚本copy到$1主机的tmp目录下
    expect "assword:"   //检测关键信息
    send "$2 "  //输出信息$2(密码),通过scp密码交互
    expect eof  //完成expect
    EOF
    }


    vib_install(){
    expect << EOF
    set timeout -1
    spawn ssh -o stricthostkeychecking=no root@$1 "sh /tmp/megacli_install.sh"
    expect "assword:"
    send "$2 "
    expect eof
    EOF
    }

    for SER in $SERVERS
    do vib_shell_copy $SER $PASSWORD &> /dev/null
    echo "$SER copy successed"
    vib_install $SER $PASSWORD &> /dev/null
    echo "$SER install successed"
    done

    测试了一下脚本没问题,在生产运行脚本,第四五台机器时脚本就走不动了,咨询一下吴老师,是scp、ssh命令会有首次交互确认的问题,选项 -o stricthostkeychecking=no 关闭主机密钥检查就OK了。

    标签: Linux shell


    巧用expect安装插件 原创
    2020-02-06

    剑侠闯江湖

    码龄16年

    关注
    背景
    某产品的插件基本都是一步步安装,需要输入一些相对比较专业的参数,对于没有接触过该产品的人而言,就不知道怎么选择。而某客户对于该插件的需求是恒定的,则可以通过expect来自动执行安装,降低了对售后人员的技术要求。

    解决方法
    !/usr/bin/expect
    spawn bash install.bin
    set openstack 11
    expect "*1*12*select:" { send "$openstack " }
    set install 1
    expect "*operation:" { send "$install " }
    set expert n
    expect "*expert*:" { send "$expert " }
    set sdnip 2009:d::101
    expect "*sdn*" { send "$sdnip " }
    set https y
    expect "*HTTPS*:" { send "$https " }
    set ssl n
    expect "*validation*" { send "$ssl " }
    set port 8443
    expect "*8443*" { send "$port " }
    set username root
    expect "*name:" { send "$username " }
    set passwd password
    expect "*password:" { send "$passwd " }
    interact

    ###sample 

    ##remove -P 22 because we meet error :exec: 22: No such file or directory
    ###add -o stricthostkeychecking=no to 首次登陆时候 提示 avoid Are you sure you want to continue connecting ###(yes/no)?

    ##remove -P 22 from sftp because we meet error :exec: 22: No such file or directory,Couldn't read packet: ##Connection reset by peer
    ##in windows nbu master : check security management _ token management : token is MVFNJBPGRJXHCMFU
    ###check another day token still is MVFNJBPGRJXHCMFU


    expect <<- EOF
    set timeout 5
    spawn sftp -o stricthostkeychecking=no useradmin@10.200.1.1

    expect {
    "(yes/no)?" {send "yes "; expect_continue }
    "*assword:" {send "user@pass "}
    }
    expect "sftp>"
    send "cd /dbsoft/nbusoft/NBU8.1 "
    expect "sftp>"
    send "lcd /tmp/nbu "
    expect "sftp>"
    set timeout -1
    send "mget rman.sh "
    expect "sftp>"
    send "mget NetBackup_8.1.2_CLIENTS2.tar.gz "
    expect "sftp>"
    send "mget rman_arc.sh "
    expect "sftp>"
    send "mget mysql_backup.sh "
    expect "sftp>"
    send "mget mysqlbackup_5.7 "
    expect "sftp>"
    send "bye "
    EOF

  • 相关阅读:
    java8新特性之Lambda表达式入门
    小结
    Kafka入门
    关于java多线程初试
    关于Netty入门
    IOS UITableView代码添加数据源和指定委托
    C#读书笔记1
    vs2008 C# Windows Mobile 智能设备开发 初步1
    Microsoft ActiveSync简介(来自网络)
    winForm单击用户区可移动窗体,代码控制窗体最大适中
  • 原文地址:https://www.cnblogs.com/feiyun8616/p/7778283.html
Copyright © 2011-2022 走看看