Linux expect远程登陆与交互

2019-06-03 21:57:39 来源: 晴天小雨 0

摘要:在配置免密登陆时,需要进行服务器或用户之间的切换并执行相应的命令,经过长时间的尝试,对成果做个记录。

expect简介

expect基于tcl的,是一个实现自动交互的脚本工具。除支持Unix/Linux平台外,它还支持Windows平台,是为系统管理和软件测试方面自动交互类需求而产生的。

expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预,是一个用来实现自动交互功能的软件套件。

安装expect

系统需已安装tcl:whereis tcl

yum install -y expect

工作原理

使用 spawn 开启一个会话,然后使用 expect-send 对来执行交互式操作。

spawn 后面跟上一个命令操作,表示开启一个会话。

expect 等待输出特定的字符串(通常是提示符)。

send 发送交互字符串。

指定脚本解释器

#!/usr/bin/expect

基本语法

命令行参数--$argc 、$argv

$argc参数个数

$argv 0 第一个命令行参数,以此类推(带空格)

$argv0 是脚本名(不带空格)

# $argc,$argv 0,$argv 1 ... $argv n
if {$argc<2} {
           send_user "Usage: $argv0 login passwaord.n "
            exit 1
}

输出或打印--send_user

send_user 用来显示信息到父进程(一般为用户的shell)的标准输出,相当于Linux shell中的echo

send_user "string"

设置变量--set

set timeout命令设置后面所有的expect命令的等待响应的超时时间(-l参数用来关闭任何超时设置)。

设置会话超时时间为30s, 若不限制超时时间则应设置为-1

set timeout 30

设置变量并赋值

set param "param_str"

设置变量为命令行参数

set password [lindex $argv 0]

命令调用--spawn

spawn 后面跟一个命令,开启一个会话或进程,expect和send都将在这个会话或进程里面运行。

而命令实际上是以衍生子进程的方式运行。

spawn su root

模式-动作expect - send

expect 接收命令执行后的输出,然后和期望字符串匹配,若对应这执行相应的send来发送交互信息。

expect等待输出中输出特定的字符,通常是一个提示符,然后发送特定的响应。

主要运用场景是接收Linux系统控制台的提示信息,如果提示信息中包含expect后面的字符串,而执行send后面的动作,即命令

单一分支模式:

expect "$case1" {send "$response1\r"}

多个分支模式:类似switch语句

expect {

"$case1" {send "$response1\r"}

"$case2" {send "$response2\r"}

"$case3" {send "$response3\r"}

timeout { }

}

判断及正则表达式运用

使用了-re参数,表示指定的的字符串是一个正则表达式

在一个正则表达时中,可以在()中包含若干个部分并通过expect_out数组访问它们

expect -re "\[(.*)]:"

if {$expect_out(1,string)!="/bin/tcsh"} {

send "/bin/tcsh" }

send " "

expect eof

结束符--interact或expect eof

expect eof :等待执行结束,若没有这一句,可能导致命令还没执行,脚本就结束了 
interact : 执行完成后保持交互状态, 这时可以手动输入信息 
:expect eof 与 interact 二选一即可

if判断

set param0 [lindex $argv 0]
if {$argc < 1} {
#do something
send_user "usage: $argv0 <param1> <param2> ... "
exit }

函数定义和调用

      proc do_console_login {login pass} { 
            ..............         

    }

循环

        while ($done) {
            ................
        }

条件分支Switch

 switch -- $timeout_case {
            0 {
              ...............
            }
            1 {
              ...............
            }
            2 {
              ...............       
            }
        }  

运算

 incr timeout_case

实战

保存为脚本文件remote_root_command.exp

#!/usr/bin/expect

if {$argc < 4} {
    #do something
    send_user "usage: $argv0 <remote_user> <remote_host> <remote_pwd> <remote_root_pwd>"
    exit
}

set timeout -1
set remote_user [lindex $argv 0] # 远程服务器用户名
set remote_host [lindex $argv 1] # 远程服务器域名
set remote_pwd [lindex $argv 2] # 远程服务器密码
set remote_root_pwd [lindex $argv 3] # 远程服务器根用户密码

# 远程登录
spawn ssh ${remote_user}@${remote_host}
expect "*assword:" {send "${remote_pwd}\r"}
expect "Last login:"

# 切换到 root
send "su\r"
expect "*assword:" {send "${remote_root_pwd}\r"}

# 执行关闭防火墙命令
send "service iptables stop\r"
send "exit\r"
send "exit\r"
expect eof

执行命令:./remote_root_command.exp <remote_user> <remote_host> <remote_pwd> <remote_root_pwd>

linux shell和expect自动交互混合编码

#!/bin/bash 
pwd='123456'
ls_date=`date +%Y-%m-%d`
expire_me="R_rhp-report_ALL_daily_"${ls_date}".txt"
curdir=$(cd $(dirname $0); pwd)
echo $pwd 
echo $expire_me
echo $curdir
/usr/bin/expect <<-EOF
spawn sftp kaifatest@reports.afilias.info;
expect {
"kaifatest@reports.afilias.info's password:" {send_user $pwd;send "$pwd\r";exp_continue}
"sftp>" {send "get $expire_me $curdir\rquit\r";exp_continue}
}
expect eof;
EOF
exit

 

脚本解释说明

#!/bin/bash  =>  shell脚本执行

全部expect:#!/usr/bin/expect

/usr/bin/expect <<-EOF => 此处开始执行expect脚本,记住EOF前面的“-”

expect中最关键的四个命令是send,expect,spawn,interact。

send:用于向进程发送字符串 
expect:从进程接收字符串 
spawn:启动新的进程 
interact:允许用户交互

spawn命令是Expect的初始命令,它用于启动一个进程,之后所有expect操作都在这个进程中进行,如果没有spawn语句,整个expect就无法再进行下去了

expect 是针对需要交互的地方进行自动发送消息,{ 大扣号前面必须要有空格,前面引号内的内容是交互界面等待输入的匹配字串,{} 内的是交互输入的内容,

send_user 等同于shell里的echo 显示用,

send 发送数据,最后的\r必需,说明输入密码并回车了

exp_continue 继续处理下一步命令

进入sftp后,需要获取所需文件并退出,因为都是在"sftp>"下面处理,所以两个命令放一起:

"sftp>" {send "get $expire_me $curdir\rquit\r";exp_continue}

expect eof =>此命令和spawn 是匹配的,spawn进程结束后会向expect发送eof,表示退出spwan

EOF 解除expect脚本执行,跳出到shell执行环境

收藏
登录发表你的评论
0条评论