找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1332|回复: 0

expect - 自动交互脚本

[复制链接]

3万

主题

7

回帖

9万

积分

管理员

积分
91233
发表于 2021-12-15 18:20:53 | 显示全部楼层 |阅读模式
expect参数
expect教程中文版
expect中文手册
expect说明
启用选项
-c:执行脚本前先执行的命令,可多次使用。
-d:debug模式,可以在运行时输出一些诊断信息,与在脚本开始处使用exp_internal 1相似。
-D:启用交换调式器,可设一整数参数。
-f:从文件读取命令,仅用于使用#!时。如果文件名为"-",则从stdin读取(使用"./-"从文件名为-的文件读取)。
-i:交互式输入命令,使用"exit"或"EOF"退出输入状态。
--:标示选项结束(如果你需要传递与expect选项相似的参数给脚本时),可放到#!行:#!/usr/bin/expect --。
-v:显示expect版本信息。
常用命令
  1. # 命令行参数
  2. # $argv,参数数组,使用[lindex $argv n]获取,$argv 0为脚本名字
  3. # $argc,参数个数
  4. set username [lindex $argv 1]  # 获取第1个参数
  5. set passwd [lindex $argv 2]    # 获取第2个参数

  6. set timeout 30 # 设置超时

  7. # spawn是expect内部命令,开启ssh连接
  8. spawn ssh -l username 192.168.1.1

  9. # 判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间(timeout)后返回
  10. expect "password:"

  11. # 发送内容ispass(密码、命令等)
  12. send "ispass\r"

  13. # 发送内容给用户
  14. send_user "$argv0 [lrange $argv 0 2]\n"
  15. send_user "It's OK\r"
  16. # 执行完成后保持交互状态,控制权交给控制台(手工操作)。否则会完成后会退出。
  17. interact
复制代码
命令介绍
close:关闭当前进程的连接。
debug:控制调试器。
disconnect:断开进程连接(进程仍在后台运行)。
定时读取密码、执行priv_prog
  1. send_user "password?\ "
  2. expect_user -re "(.*)\n"
  3. for {} 1 {} {
  4.     if {[fork]!=0} {sleep 3600;continue}
  5.     disconnect
  6.     spawn priv_prog
  7.     expect Password:
  8.     send "$expect_out(1,string)\r"
  9.     . . .
  10.     exit
  11. }
复制代码
exit:退出expect。
exp_continue [-continue_timer]:继续执行下面的匹配。
exp_internal [-f file] value:
expect范例
自动telnet会话
  1. #!/usr/bin/expect -f
  2. set ip [lindex $argv 0 ]         # 接收第1个参数,作为IP
  3. set userid [lindex $argv 1 ]     # 接收第2个参数,作为userid
  4. set mypassword [lindex $argv 2 ] # 接收第3个参数,作为密码
  5. set mycommand [lindex $argv 3 ]  # 接收第4个参数,作为命令
  6. set timeout 10                   # 设置超时时间

  7. # 向远程服务器请求打开一个telnet会话,并等待服务器询问用户名
  8. spawn telnet $ip
  9.     expect "username:"
  10.     # 输入用户名,并等待服务器询问密码
  11.     send "$userid\r"
  12.     expect "password:"
  13.     # 输入密码,并等待键入需要运行的命令
  14.     send "$mypassword\r"
  15.     expect "%"
  16.     # 输入预先定好的密码,等待运行结果
  17.     send "$mycommand\r"
  18.     expect "%"
  19.     # 将运行结果存入到变量中,显示出来或者写到磁盘中
  20.     set results $expect_out(buffer)
  21.     # 退出telnet会话,等待服务器的退出提示EOF
  22.     send "exit\r"
  23.     expect eof
复制代码
自动建立FTP会话
  1. #!/usr/bin/expect -f
  2. set ip [lindex $argv 0 ]         # 接收第1个参数,作为IP
  3. set userid [lindex $argv 1 ]     # 接收第2个参数,作为Userid
  4. set mypassword [lindex $argv 2 ] # 接收第3个参数,作为密码
  5. set timeout 10                   # 设置超时时间

  6. # 向远程服务器请求打开一个FTP会话,并等待服务器询问用户名
  7. spawn ftp $ip
  8.     expect "username:"
  9.     # 输入用户名,并等待服务器询问密码
  10.     send "$userid\r"
  11.     expect "password:"
  12.     # 输入密码,并等待FTP提示符的出现
  13.     send "$mypassword\r"
  14.     expect "ftp>"
  15.     # 切换到二进制模式,并等待FTP提示符的出现
  16.     send "bin\r"
  17.     expect "ftp>"
  18.     # 关闭ftp的提示符
  19.     send "prompt\r"
  20.     expect "ftp>"
  21.     # 下载所有文件
  22.     send "mget *\r"
  23.     expect "ftp>"
  24.     # 退出此次ftp会话,并等待服务器的退出提示EOF
  25.     send "bye\r"
  26.     expect eof
复制代码
自动登录ssh执行命令
  1. #!/usr/bin/expect
  2. set IP     [lindex $argv 0]
  3. set USER   [lindex $argv 1]
  4. set PASSWD [lindex $argv 2]
  5. set CMD    [lindex $argv 3]

  6. spawn ssh $USER@$IP $CMD
  7. expect {
  8.     "(yes/no)?" {
  9.         send "yes\r"
  10.         expect "password:"
  11.         send "$PASSWD\r"
  12.         }
  13.     "password:" {send "$PASSWD\r"}
  14.     "* to host" {exit 1}
  15.     }
  16. expect eof
复制代码
自动登录ssh
  1. #!/usr/bin/expect -f  
  2. set ip [lindex $argv 0 ]         # 接收第1个参数,作为IP
  3. set username [lindex $argv 1 ]   # 接收第2个参数,作为username
  4. set mypassword [lindex $argv 2 ] # 接收第3个参数,作为密码
  5. set timeout 10                   # 设置超时时间

  6. spawn ssh $username@$ip       # 发送ssh请求
  7. expect {                      # 返回信息匹配
  8. "*yes/no" { send "yes\r"; exp_continue}  # 第一次ssh连接会提示yes/no,继续  
  9. "*password:" { send "$mypassword\r" }    # 出现密码提示,发送密码  
  10. }
  11. interact        # 交互模式,用户会停留在远程服务器上面
复制代码
批量登录ssh服务器执行操作范例,设定增量的for循环
  1. #!/usr/bin/expect
  2. for {set i 10} {$i <= 12} {incr i} {
  3.     set timeout 30
  4.     set ssh_user [lindex $argv 0]
  5.     spawn ssh -i .ssh/$ssh_user abc$i.com

  6.     expect_before "no)?" {
  7.     send "yes\r" }
  8.     sleep 1
  9.     expect "password*"
  10.     send "hello\r"
  11.     expect "*#"
  12.     send "echo hello expect! > /tmp/expect.txt\r"
  13.     expect "*#"
  14.     send "echo\r"
  15. }
  16. exit
复制代码
批量登录ssh并执行命令,foreach语法
  1. #!/usr/bin/expect
  2. if {$argc!=2} {
  3.     send_user "usage: ./expect ssh_user password\n"
  4.     exit
  5. }
  6. foreach i {11 12} {
  7.     set timeout 30
  8.     set ssh_user [lindex $argv 0]
  9.     set password [lindex $argv 1]
  10.     spawn ssh -i .ssh/$ssh_user root@xxx.yy.com
  11.     expect_before "no)?" {
  12.     send "yes\r" }
  13.     sleep 1

  14.     expect "Enter passphrase for key*"
  15.     send "password\r"
  16.     expect "*#"
  17.     send "echo hello expect! > /tmp/expect.txt\r"
  18.     expect "*#"
  19.     send "echo\r"
  20. }
  21. exit
复制代码
另一自动ssh范例,从命令行获取服务器IP,foreach语法,expect嵌套
  1. #!/usr/bin/expect
  2. # 使用方法: script_name ip1 ip2 ip3 ...

  3. set timeout 20
  4. if {$argc < 1} {
  5.   puts "Usage: script IPs"
  6.   exit 1
  7. }
  8. # 替换你自己的用户名
  9. set user "username"
  10. #替换你自己的登录密码
  11. set password "yourpassword"

  12. foreach IP $argv {
  13. spawn ssh $user@$IP

  14. expect \
  15.   "(yes/no)?" {
  16.     send "yes\r"
  17.     expect "password:?" {
  18.       send "$password\r"
  19.     }
  20.   } "password:?" {
  21.     send "$password\r"
  22. }

  23. expect "\$?"
  24. # 替换你要执行的命令
  25. send "last\r"
  26. expect "\$?"
  27. sleep 10
  28. send "exit\r"
  29. expect eof
  30. }
复制代码
批量ssh执行命令,用shell调用tclsh方式、多进程同时执行
tclsh - Simple shell containing Tcl interpreter
  1. #!/bin/sh
  2. # -*- tcl -*- \
  3. exec tclsh $0 "$@"
  4. package require Expect
  5. set username [lindex $argv 0]
  6. set password [lindex $argv 1]
  7. set argv [lrange $argv 2 end]
  8. set prompt "(%|#|\\$) $"
  9. foreach ip $argv {
  10.     spawn ssh -t $username@$ip sh
  11.     lappend ids $spawn_id
  12. }
  13. expect_before -i ids eof {
  14.     set index [lsearch $ids $expect_out(spawn_id)]
  15.     set ids [lreplace $ids $index $index]
  16.     if [llength $ids] exp_continue
  17. }
  18. expect -i ids "(yes/no)\\?" {
  19.     send -i $expect_out(spawn_id) yes\r
  20.     exp_continue
  21. } -i ids "Enter passphrase for key" {
  22.     send -i $expect_out(spawn_id) \r
  23.     exp_continue
  24. } -i ids "assword:" {
  25.     send -i $expect_out(spawn_id) $password\r
  26.     exp_continue
  27. } -i ids -re $prompt {
  28.     set spawn_id $expect_out(spawn_id)
  29.     send "echo hello; exit\r"
  30.     exp_continue
  31. } timeout {
  32.     exit 1
  33. }
复制代码
ssh登录过程常规提示文字
  1. The authenticity of host '192.168.17.35 (192.168.17.35)' can't be established.
  2. RSA key fingerprint is 25:e8:4c:89:a3:b2:06:ee:de:66:c7:7e:1b:fa:1c:c5.
  3. Are you sure you want to continue connecting (yes/no)?


  4. Warning: Permanently added '192.168.17.35' (RSA) to the list of known hosts.
  5. Enter passphrase for key '/data/key/my_dsa':


  6. Last login: Sun Jan 26 13:39:37 2014 from 192.168.11.143
  7. [root@master003 ~]#


  8. root@192.168.16.90's password:


  9. Last login: Thu Jan 23 17:50:43 2014 from 192.168.11.102
  10. [root@lvsmaster ~]#
复制代码
ssh自动登录expect脚本:ssh.expect
  1. #!/usr/bin/expect -f
  2. # Auther:YuanXing
  3. # Update:2014-02-08
  4. if {$argc < 4} {
  5.     send_user "Usage:\n  $argv0 IPaddr User Passwd Port Passphrase\n"
  6.     puts stderr "argv error!\n"
  7.     sleep 1
  8.     exit 1
  9. }

  10. set ip         [lindex $argv 0 ]
  11. set user       [lindex $argv 1 ]
  12. set passwd     [lindex $argv 2 ]
  13. set port       [lindex $argv 3 ]
  14. set passphrase [lindex $argv 4 ]
  15. set timeout 6
  16. if {$port == ""} {
  17.     set port 22
  18. }
  19. #send_user "IP:$ip,User:$user,Passwd:$passwd,Port:$port,Passphrase:$passphrase"
  20. spawn ssh -p $port $user@$ip

  21. expect_before "(yes/no)\\?" {
  22.     send "yes\r"}

  23. expect \
  24. "Enter passphrase for key*" {
  25.     send "$passphrase\r"
  26.     exp_continue
  27. } " password:?" {
  28.     send "$passwd\r"
  29.     exp_continue
  30. } "*\[#\\\$]" {
  31.     interact
  32. } "* to host" {
  33.     send_user "Connect faild!"
  34.     exit 2
  35. } timeout {
  36.     send_user "Connect timeout!"
  37.     exit 2
  38. } eof {
  39.     send_user "Lost connect!"
  40.     exit
  41. }
复制代码
Mikrotik backup script using ssh and expect
http://www.pmoghadam.com/homepag ... ipt-ssh-expect.html
  1. #!/bin/bash
  2. # BY: Pejman Moghadam
  3. # TAG: mikrotik, ssh, expect, lftp
  4. # DATE: 2012-05-27 14:42:14

  5. BACKUP_DIR="/var/backups"
  6. HOSTNAME="192.168.88.1"
  7. PORT="22"
  8. USER="admin"
  9. PASS="123456"
  10. TMP=$(mktemp)
  11. TODAY=$(date +%F)
  12. FILENAME="$HOSTNAME-$TODAY"
  13. PATH="/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin"

  14. # create expect script
  15. cat > $TMP << EOF
  16. #exp_internal 1 # Uncomment for debug
  17. set timeout -1
  18. spawn ssh -p$PORT $USER@$HOSTNAME
  19. match_max 100000
  20. expect -exact "password:"
  21. send -- "$PASS\r"
  22. sleep 1
  23. expect " > "
  24. send -- "/export file=$FILENAME\r"
  25. expect " > "
  26. send -- "/system backup save name=$FILENAME\r"
  27. expect " > "
  28. send -- "quit\r"
  29. expect eof
  30. EOF

  31. # run expect script
  32. #cat $TMP # Uncomment for debug
  33. expect -f $TMP

  34. # remove expect script
  35. rm $TMP

  36. # download and remove backup files
  37. # "xfer:clobber on" means overwrite existing files
  38. cd ${BACKUP_DIR}
  39. echo "
  40.   set xfer:clobber on
  41.   get ${FILENAME}.rsc
  42.   rm ${FILENAME}.rsc
  43.   get ${FILENAME}.backup
  44.   rm ${FILENAME}.backup" |
  45. lftp -u $USER,$PASS $HOSTNAME
复制代码
转自
http://xstarcd.github.io/wiki/shell/expect.html

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|番茄论坛

GMT+8, 2024-11-21 19:24 , Processed in 0.081961 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表