如何从机器A上ssh到机器B上,然后执行机器B上的命令?如何使之自动化完成?看完下面的文章你就明白了

一、安装

expect 是基于tcl 演变而来的,所以很多语法和tcl 类似

sudo apt-get install tcl tk expect

或者

yum install -y tcl tclx tcl-devel

二、如何使用

expect是linux中的一个用来处理交互的命令。借助Expect,我们可以将交互过程写在一个脚本上,使之自动化完成。形象的说,ssh登录,ftp登录等都符合交互的定义。下文我们首先提出一个问题,然后介绍基础知四个命令

四个命令

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

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

1、send

send命令接收一个字符串参数,并将该参数发送到进程。

expect1.1> send "hello world\n"
hello world

2. expect命令

启用选项

  • -c:执行脚本前先执行的命令,可多次使用。

  • -d:debug模式,可以在运行时输出一些诊断信息,与在脚本开始处使用exp_internal 1相似。

  • -D:启用交换调式器,可设一整数参数。

  • -f:从文件读取命令,仅用于使用#!时。如果文件名为"-",则从stdin读取(使用"./-"从文件名为-的文件读取)。

  • -i:交互式输入命令,使用"exit"或"EOF"退出输入状态。

  • --:标示选项结束(如果你需要传递与expect选项相似的参数给脚本时),可放到#!行:#!/usr/bin/expect --

  • -v:显示expect版本信息。

expect命令和send命令正好相反,expect通常是用来等待一个进程的反馈。expect可以接收一个字符串参数,也可以接收正则表达式

expect "hi\n"
send "hello there!\n"

这两行代码的意思是:从标准输入中等到hi和换行键后,向标准输出输出hello there。

看一段代码:

#!/usr/bin/expect -f
expect "hi\n"
send "you typed <$expect_out(buffer)>"
send "but I only expected <$expect_out(0,string)>"

执行结果

1
2
3
4
5
hi
you typed <1
2
3
4
5
hi
>but I only expected <hi

多分支模式

expect "hi" { send "You said hi\n" } \
"hello" { send "Hello yourself\n" } \
"bye" { send "That was unexpected\n

或者下面的写法

expect {
"hi" { send "You said hi\n"}
"hello" { send "Hello yourself\n"}
"bye" { send "That was unexpected\n"}
}

3、spawn

spawn命令就是用来启动新的进程的,比如登录ftp

spawn ftp ftp.test.com

4、interact

interact ##是Expect用来打开用户与产生进程之间通信的命令,简单说就是登陆以后将远程服务器的终端保持在当前终端,而不是将远程终端关掉

#!/usr/bin/expect -f
set timeout -1
spawn ssh $user@$host
expect -exact  "password"
send "$password\n"
send --  "pwd\n"
interacter

三、总结

1、常用命令

# 命令行参数
# $argv,参数数组,使用[lindex $argv n]获取,$argv 0为脚本名字
# $argc,参数个数
set username [lindex $argv 1]  # 获取第1个参数
set passwd [lindex $argv 2]    # 获取第2个参数set timeout 30 # 设置超时# spawn是expect内部命令,开启ssh连接
spawn ssh -l username 192.168.1.1# 判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间(timeout)后返回
expect "password:"# 发送内容ispass(密码、命令等)
send "ispass\r"# 发送内容给用户
send_user "$argv0 [lrange $argv 0 2]\n"
send_user "It's OK\r"
# 执行完成后保持交互状态,控制权交给控制台(手工操作)。否则会完成后会退出。
interact

2、命令介绍

  • close:关闭当前进程的连接。
  • debug:控制调试器。
  • disconnect:断开进程连接(进程仍在后台运行)。
  • 执行priv_prog:定时读取密码
  • exit:退出expect。
  • exp_continue [-continue_timer]:继续执行下面的匹配。
  • exp_internal [-f file] value:
send_user "password?\ "
expect_user -re "(.*)\n"
for {} 1 {} {if {[fork]!=0} {sleep 3600;continue}disconnectspawn priv_progexpect Password:send "$expect_out(1,string)\r". . .exit
}

3、范例

A、自动telnet会话

#!/usr/bin/expect -f
set ip [lindex $argv 0 ]         # 接收第1个参数,作为IP
set userid [lindex $argv 1 ]     # 接收第2个参数,作为userid
set mypassword [lindex $argv 2 ] # 接收第3个参数,作为密码
set mycommand [lindex $argv 3 ]  # 接收第4个参数,作为命令
set timeout 10                   # 设置超时时间# 向远程服务器请求打开一个telnet会话,并等待服务器询问用户名
spawn telnet $ipexpect "username:"# 输入用户名,并等待服务器询问密码send "$userid\r"expect "password:"# 输入密码,并等待键入需要运行的命令send "$mypassword\r"expect "%"# 输入预先定好的密码,等待运行结果send "$mycommand\r"expect "%"# 将运行结果存入到变量中,显示出来或者写到磁盘中set results $expect_out(buffer)# 退出telnet会话,等待服务器的退出提示EOFsend "exit\r"expect eof

B、自动建立FTP会话

#!/usr/bin/expect -f
setip [lindex $argv 0 ]         # 接收第1个参数,作为IP
setuserid [lindex $argv 1 ]     # 接收第2个参数,作为Userid
setmypassword [lindex $argv 2 ] # 接收第3个参数,作为密码
settimeout 10                   # 设置超时时间
# 向远程服务器请求打开一个FTP会话,并等待服务器询问用户名
spawn ftp$ipexpect "username:"# 输入用户名,并等待服务器询问密码send "$userid\r"expect "password:"# 输入密码,并等待FTP提示符的出现send "$mypassword\r"expect "ftp>"# 切换到二进制模式,并等待FTP提示符的出现send "bin\r"expect "ftp>"# 关闭ftp的提示符send "prompt\r"expect "ftp>"# 下载所有文件send "mget *\r"expect "ftp>"# 退出此次ftp会话,并等待服务器的退出提示EOFsend "bye\r"expect eof

C、自动登录ssh执行命令

#!/usr/bin/expect
set IP     [lindex $argv 0]
set USER   [lindex $argv 1]
set PASSWD [lindex $argv 2]
set CMD    [lindex $argv 3]spawn ssh $USER@$IP $CMD
expect {"(yes/no)?" {send "yes\r"expect "password:"send "$PASSWD\r"}"password:" {send "$PASSWD\r"}"* to host" {exit 1}}
expect eof

D、批量登录ssh服务器执行操作范例,设定增量的for循环

#!/usr/bin/expect
for {set i 10} {$i <= 12} {incr i} {set timeout 30set ssh_user [lindex $argv 0]spawn ssh -i .ssh/$ssh_user abc$i.comexpect_before "no)?" {send "yes\r" }sleep 1expect "password*"send "hello\r"expect "*#"send "echo hello expect! > /tmp/expect.txt\r"expect "*#"send "echo\r"
}
exit

E、批量登录ssh并执行命令,foreach语法

#!/usr/bin/expect
if {$argc!=2} {send_user "usage: ./expect ssh_user password\n"exit
}
foreach i {11 12} {set timeout 30set ssh_user [lindex $argv 0]set password [lindex $argv 1]spawn ssh -i .ssh/$ssh_user root@xxx.yy.comexpect_before "no)?" {send "yes\r" }sleep 1expect "Enter passphrase for key*"send "password\r"expect "*#"send "echo hello expect! > /tmp/expect.txt\r"expect "*#"send "echo\r"
}
exit

F、从命令行获取服务器IP,foreach语法,expect嵌套

#!/usr/bin/expect
# 使用方法: script_name ip1 ip2 ip3 ...set timeout 20
if {$argc < 1} {puts "Usage: script IPs"exit 1
}
# 替换你自己的用户名
set user "username"
#替换你自己的登录密码
set password "yourpassword"foreach IP $argv {
spawn ssh $user@$IPexpect \"(yes/no)?" {send "yes\r"expect "password:?" {send "$password\r"}} "password:?" {send "$password\r"
}expect "\$?"
# 替换你要执行的命令
send "last\r"
expect "\$?"
sleep 10
send "exit\r"
expect eof
}

G、ssh自动登录expect脚本

#!/usr/bin/expect -f
# Auther:YuanXing
# Update:2014-02-08
if {$argc < 4} {send_user "Usage:\n  $argv0 IPaddr User Passwd Port Passphrase\n"puts stderr "argv error!\n"sleep 1exit 1
}set ip         [lindex $argv 0 ]
set user       [lindex $argv 1 ]
set passwd     [lindex $argv 2 ]
set port       [lindex $argv 3 ]
set passphrase [lindex $argv 4 ]
set timeout 6
if {$port == ""} {set port 22
}
#send_user "IP:$ip,User:$user,Passwd:$passwd,Port:$port,Passphrase:$passphrase"
spawn ssh -p $port $user@$ipexpect_before "(yes/no)\\?" {send "yes\r"}expect \
"Enter passphrase for key*" {send "$passphrase\r"exp_continue
} " password:?" {send "$passwd\r"exp_continue
} "*\[#\\\$]" {interact
} "* to host" {send_user "Connect faild!"exit 2
} timeout {send_user "Connect timeout!"exit 2
} eof {send_user "Lost connect!"exit
}

H、通过shell脚本调用

#!/bin/bashTMP=$(mktemp)
username=(test)
# create expect scriptfor ip in `cat ip.txt`; docat > $TMP << EOF
set timeout 5
spawn  ssh  -i  $username/id_rsa   -p888   $username@$ipexpect -exact "$username"
send --  "su - \r\n"expect -exact "Password"
send --  "213f214##!ds(*&a@\r\n"expect -exact "root"
send --  "userdel -r zhangshan\r\n"
send --  "userdel -r lisi\r\n"send --  "history -c \r\n exit\r\n"
send --  "history -c \r\n exit\r\n"
expect eofEOFexpect -f $TMP
rm $TMP
done

  

linux expect 自动交互命令 总结相关推荐

  1. linux expect 自动交互 执行命令 超时 不完整 中断 解决方法

    使用 expec t自动交互执行命令时,默认超时timeout为30s 手动添加set timeout -1设置 超时时间为无穷大 就可以执行完命令了 通过expect执行scp,传输文件不完整 写了 ...

  2. 教会你Linux Shell自动交互的三种方法

    你了解Linux系统么?你是Linux系统的应用者么?如果你要学习linux,你可能会遇到Linux Shell自动交互问题,这里将介绍Linux Shell自动交互的解决方法,在这里拿出来和大家分享 ...

  3. linux自动点击软件上的按钮有什么用,教会你Linux Shell自动交互的三种方法

    你了解Linux系统么?你是Linux系统的应用者么?如果你要学习linux,你可能会遇到Linux Shell自动交互问题,这里将介绍Linux Shell自动交互的解决方法,在这里拿出来和大家分享 ...

  4. linux 命令行模式自动登录,实现linux的自动登录--命令行模式启动

    linux的登录主要是由两个文件在控制,/usr/sbin/getty来获得用户名,并进行检查用户名是否存在,然后将用户名传递给/usr/bin/login来获取用户输入密码和检查密码是否正确. 所以 ...

  5. linux expect自动登录ssh,ftp

    expect是一种能够按照脚本内容里面设定的方式与交互式程序进行"会话"的程序.根据脚本内容,Expect可以知道程序会提示或反馈什么内容以及 什么是正确的应答.它是一种可以提供& ...

  6. 以某一用户名和密码 登录请求脚本_linux expect自动交互脚本

    1.expect参数 2.启用选项 -c :执行脚本前先执行的命令,可多次使用.-d :debug模式,可以在运行时输出一些诊断信息,与在脚本开始处使用 exp_internal 1 相似.-D :启 ...

  7. linux开机自动执行命令或自动启动程序(rc.local)

    linux开机的最后会执行/etc/rc.local,因此可以在此脚本里面添加shell命令自动执行或者自动启动某个进程. 比如 自动输出信息: #!/bin/sh -e # # rc.local # ...

  8. linux 开机自动运行命令_如何在Linux终端同时运行多个Linux命令

    在一行中运行两个或多个命令可以节省大量时间,并在Linux中提高效率.在Linux中,有三种方法可以在一行中运行多个命令: ; Command 1 ; Command 2 首先运行Command1,然 ...

  9. linux开机自动执行命令

    /etc/rc.local是/etc/rc.d/rc.local的软链,像windos的快捷方式 开机自动执行的命令在此文件尾部exit 0 之前输入即可 给/etc/rc.local文件添加执行权限 ...

最新文章

  1. 如何利用AI语义分析,做产品需求分析(1)
  2. flutter 自定义tab导航-顶部导航-底部导航
  3. mysql锁与程序锁_数据库加锁(转)
  4. ACM基础题 - 求矩形个数
  5. 你所需要的java基础篇和提升篇大总结
  6. 从零开始入门 K8s | etcd 性能优化实践
  7. [知识图谱实战篇] 二.Json+Seaborn可视化展示电影实体
  8. Linux发行版的关系图
  9. matlab figure被图像填充
  10. 内核抢占会让内核调度更好吗?
  11. python字符串前面加上序号_简单了解python字符串前面加r,u的含义
  12. 蓝桥杯 ALGO-159 算法训练 P0103
  13. elman神经网络的实现
  14. html 卫星地图显示地名,卫星图看:河南10个名字非常好听的县(区),你认识几个?...
  15. 【编译原理】自上而下语法分析(C/C++源码+实验报告)
  16. 梁德伟-唯品会物流信息部技术部应用架构实践总结
  17. Codeforces Gym 100015B Ball Painting 找规律
  18. Web编程入门暨个人网站计划:Web前端开发入门
  19. UE战棋游戏的制作流程(使用GAS来制作技能系统)
  20. http工作中常见的状态码

热门文章

  1. python100以内自然数之和_python—100以内素数之和 python123
  2. 5G NPN 行业专网 — Overview
  3. 系统学英语 —语法— 句子成分
  4. SQLite 版本引发的 Python 程序调用问题
  5. altium designer怎么在原理图中批量修改元件封装
  6. c# asp.net core取当月第一天和最后一天及删除最后一个字符的多种方法
  7. Redis分布式锁 Spring Schedule实现任务调度
  8. windows redis安装与配置
  9. Java客户端访问HBase集群解决方案(优化)
  10. Eclipse Open J9:Eclipse OMR项目提供的开源JVM