转 在shell脚本中使用expect实现scp传输问题

摘要:
本文中使用了预期5.45和tcl8.6.6。安装tcl[root@tseg0/]$mkdir/tools[root@tseg0/]$tar-zxvftcl8.6.6-src.tar。广州[root@tseg0/]$cdtcl8.6.6/unix/[root@tseg0 /]$./配置[root@tseg0/]$制造[root@tseg0/]$makeinstall123456安装需要[root@tseg0/]$cd/tools[root@tseg0/]$tar-zxvfexpect5.45.tar。广州[root@tseg0/]$cdexpect5.45/[root@tseg0/]$./configure--使用tcl=/usr/local/lib/--使用tclinclude=/tools/tcl8.6.6/generic/[root@tseg0/]$制造[root@tseg0/]$makeinstall123456 shell脚本实现scp传输命令解释-c表示可以在命令行执行except脚本;spawn命令激活一个unix程序进行交互,这是稍后要执行的命令;expect“aaa”表示程序正在等待这个aaa字符串;发送将字符串发送到程序。期望和发送经常成对出现。例如,当期望“aaa”时,发送“bbb”/bin/shexportpass=12346exportname=rootexpect-c“spawnscp-r/home/tseg/hello$name@10.103.240.33:/home/$name/expect{“*assword”{settimeout-1;send“$pass”;exp_continue;}“是/否”{发送“是”;}}expectof“settimeout-1-------˃˃˃˃˃请注意,这里的-1表示永不超时,即在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 文件下载
转 在shell脚本中使用expect实现scp传输问题第1张
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

 

########感谢AlexYBB 

linux expect中的timeout设定
转 在shell脚本中使用expect实现scp传输问题第2张
AlexYBB 2015-04-29 19:14:58 转 在shell脚本中使用expect实现scp传输问题第3张 13261 转 在shell脚本中使用expect实现scp传输问题第4张 收藏 4
分类专栏: shell脚本
 

在做日志分析工具时,发现在屏幕上拿到日志结果会有点慢,然后查了一下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

免责声明:文章转载自《转 在shell脚本中使用expect实现scp传输问题》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇NPOI随笔——图片在单元格等比缩放且居中显示Python——教你画朵太阳花下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Shell篇(三)TC Shell

Shell脚本的首行一般写为"#!+路径"来告诉系统,以路径所指定的程序来解释此脚本。              可以写为 #! /bin/tcsh -f (-f表示快速启动,不启动~/.tcshrc) Shell中的单引号' '  表示当Shell碰见第一个单引号时,它会忽略其后直到右引号的所有特殊字符。一般可用在alias              a...

Linux shell awk中printf使用

printf 是 awk 的重要格式化输出命令printf格式化输出内容 格式:printf format,item1,item2...要点: 1,printf输出时要指定格式format2,formay用于指定后面的每个item输出的格式3,printf语句不会自动打印换行符 format格式: %c:显示单个字符%d,%i:十进制整数%e,%E:科学...

Docker学习—DockerFile

前言:  上一篇文章简单使用了docker 拉取镜像、启动容器、编译镜像;其中编译镜像时,使用到了Dockerfile,那么接下来我们就详细的来说说Dockerfile DockerFile是什么:   Dockerfile 是一个用来构建镜像的文本文件,Dockerfile内容中包含了一条条构建镜像所需的指令和说明。最终采用docker build 命令...

Sublime Text3 安装ftp插件

sublime有个叫sftp的插件,可以通过它直接打开远程机器上的文件进行编辑,并在保存后直接同步到远程linux服务器上。 用Package Control安装插件 按下Ctrl+Shift+P调出命令面板 输入install 调出 Install Package 选项并回车,然后输入FTP,下拉列表中会出现一些相关的插件, 选中SFTP进行安装就行了,...

shell脚本基本语法

以下是初学shell脚本练习过程,涉及到内容的输出、基本的计算、条件判断(if、case)、循环控制、数组的定义和使用、函数定义和使用 shell脚本内容: #! /bin/bashecho "current sh file name $0 ${0} $0_file"echo $$ #加乘除运算value=`expr 2 + 2`echo "total v...

linux shell中读写操作mysql数据库

本文介绍了如何在shell中读写mysql数据库。主要介绍了如何在shell 中连接mysql数据库,如何在shell中创建数据库,创建表,插入csv文件,读取mysql数据库,导出mysql数据库为xml或html文件, 并分析了核心语句。本文介绍的方法适用于PostgreSQL ,相对mysql而言,shell 中读写PostgreSQL会更简单些。1...