找回密码
 注册
查看: 3907|回复: 1

用expect写交互式shell脚本之expect 执行顺序

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2017-12-22 16:37:15 | 显示全部楼层 |阅读模式
在linux下写shell脚本是非常有用的,当然,交互式shell脚本更是受到欢迎。expect的简单易用性,使它受到了大家的关注。今天在写expect脚本时遇到一个问题,下面是我对问题的理解:
/ Z! w) }6 l. {" T3 K2 T# @4 q      先看下面“写法一”:2 A: M2 j7 C1 y1 |
.........         1 Z4 m% _# ]- R( F4 {! a$ H
    expect   "A"   send "AA"
! j8 \; _; _; I    expect "B"  send "BB"
3 R1 d; D1 k& F6 h+ a* d" s4 q2 g....; x+ p% A: g) e& K
刚开始,我以为程序会一个个检查,当出现expect的内容时,发送相应内容,当不出现时直接跳到下一个expect。
2 {# a/ s5 Q" i: W; |; v比如: 1.正常交互顺序 3 ?& j3 G7 J! S, b* a9 ?
要求输入A内容时,send "AA"* `5 h0 Q8 m6 L
要求输入B内容时,send "BB"
* R. H; k) Q- N% ^   2.不确定的交互,有些交互在某种情况下出现,有些不出现,下面的例子将举例
  _8 ?. s, X/ o" k2 p                不用输入A了,直接要求输入B内容时,send“BB”
3 {% R+ r, ]: m对于第二种情况,按我以前的理解写法一是可以的,当期望的A交互没出现而交互B出现了,会直接跳过,但事实不是这,它会阻塞,一直等到A交互出现。因此,当有些应用的脚本交互的内容不确定时,写法一将不通用。下面这个例子是我遇到的实例,写一个shell脚本实现远程登录,
2 F( [# P0 i% o$ k" |     写法二:
1 w5 K( h2 u. L1 x2 {. B3 y                 spawn ssh -l username 192.168.1.1! n- l0 G- d7 r8 J
          expect "(yes/no)?"  send "yes"- J" Y4 ~' y5 q8 k+ ]$ q. i$ `
   expect "password:" send "AAAA"
. Q( W, `( q% h2 E. U3 h$ `          interact
1 S4 }; e3 v, J0 p3 F0 C3 }2 ?4 f7 K3 e         这个脚本是不行的,大家知道,第一次ssh一个远程主机时会出现yes/no的交互,当以后ssh时不会出现,而是只出现第二个,按照上述分析的原因,此脚本第一次时使用时没有问题的,以后再使用时会出现阻塞,因为它一直在等待yes/no的交互,不会跳过去。因此,如果想写一个通用的脚本,就要在交互要求不确定时,跳过一些,最终的写法如下:$ z/ x1 j% g- W% a" ]
写法三:' q3 I( `" x6 ~3 l- Z; X' d
       spawn ssh -l username 192.168.1.13 P9 Z$ R# n/ k
expect{& G- I' L  n/ {; O
"(yes/no)?" { send "yes"; exp_continue}
" r( E1 N6 {( h; N "password:" {send "AAAA"}
; [% t- x. u  G         }
& V" _% u0 c  a' o4 R3 N interact
/ V) @" N  b4 ~3 O这里可以理解为expect块,当出现yes/no交互式当然send相应内容,当没有出现,而是出现password时也不会阻塞,而是执行相应的send。理解时可以联想case语句块。

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2017-12-22 17:12:25 | 显示全部楼层
echo | ssh -l root passwd --stdin
8 g6 l8 e: k7 j0 P7 becho "newpass" | ssh -l root 10.11.103.151 passwd --stdin dewang/ t0 w  x9 [& ?6 |7 L
root@10.11.103.151's password: 0 B% @* w4 W# V0 a7 G
Changing password for user dewang.
4 c1 g3 e# C  Y, _& \; j" @passwd: all authentication tokens updated successfully.
; ~6 _3 v! I3 {
3 G- B) R6 ]  R8 ]* q5 W) c+ n, y! W) V5 Q& @
#!/usr/bin/expect' M! x) i: p; l! Q% Q  N
#@brief to change user password by ssh remote machine9 @; g9 Z4 F5 l, M- A& d2 z" U2 V

; J. a8 A, n( iproc usage {funcname} {
# m. Q  L- f9 y& l6 t+ J4 c% ^8 `    puts "Usage: "
2 E3 \$ N( x# a+ b    puts "    $funcname -user "
/ J, i" A  ]- Q    puts "    $funcname -root "- w% o4 {2 q9 V& Q. W% v
}   8 `2 m8 o5 X+ h0 n0 M# A% p
( m  O$ u" _- V/ d. O# |2 k0 {- z4 h
# check param& D; r# Q1 y$ D
if { $argc != 5 } {
4 ?, @0 |+ e2 ~3 X    usage $argv0 3 [5 R1 t9 R' @- k
    exit 1
  o; v1 [2 T1 |}
4 P: ?2 ]3 ]) f, x) Y4 q9 u* L0 Q5 G+ F3 f1 l
# get param
# a9 B. B, [2 X4 `# Z* s2 T5 Fset host [lindex $argv 0]
' {9 U0 T7 Q& cset username [lindex $argv 1]
) A" ]& W& x* H) h/ K. N/ Qset newpasswd [lindex $argv 2]1 S) E: Y( U/ p/ V  }/ Y$ F+ Q
set loginname "root"  c) i$ l) k1 b* N7 _4 a' |
if { [string compare [lindex $argv 3] "-user"] == 0 } {
9 r5 p) v4 e$ }" _5 y5 ]    set loginname $username. \* g) ?/ t6 W" L8 n, \/ s: L* h- B
}
  g) u# [7 V4 A/ e9 I5 |9 uset passwd [lindex $argv 4]0 h! Q$ H2 a! \8 ^' w
puts "$host $username $newpasswd $loginname $passwd"
! M2 d0 R7 w/ z( S
  ?4 {* n6 b8 G! r% Z3 Yspawn ssh -l $loginname $host' F. J& p8 z. e3 j- |" ^4 Q$ Z% f
expect {* M# J* A' i- S1 f% c0 z
"*(yes/no)*" { send "yes\r"; set sshkey 1 }
2 L  O! ~& J0 s* i( o" i- C"*assword:*" { send "$passwd\r"; set sshkey 0 }
" W9 C# n8 ?# `9 A# K$ x' @% ^0 wif sshkey == 1 {: `% X( }9 o+ C( R+ x  a' B
    expect "*password:*"
; r4 V' }2 t% |    send "$passwd\r"
9 h' z- ?% A% b}+ Y4 r" X5 ]6 X7 E* f  a
}
& {* Q* L' @- F! yexpect "*#"8 {+ C' E9 }1 B
# I1 i2 s7 @% `1 [, N% k+ {( r
if { [string compare $loginname "root"] == 0 } {
) e0 H+ i9 h3 n* [8 x7 q    #send "echo \"$username:$newpasswd\" | chpasswd\r"2 {1 R1 I; \7 x- O) T- I) z* c$ y
    send "echo \"$newpasswd\" | passwd --stdin \"$username\"\r". q  B' s; ?: G: _3 B9 L5 m
} else {
4 i, |9 v  h. O& v# _    send "passwd\r"' Q2 o* q! ?6 n$ X* m* {; t
    expect {6 U1 N" I/ E, `5 D3 L
    "*current*assword:" {send "$passwd\r"}3 V% F2 M, A% N2 x+ J6 s
    "passwd: Authentication token manipulation error" {exit}
$ Q: K! [, H6 J    }- c4 M5 F( t: V( v9 _  N
    expect "New*assword:"9 ]: p0 a! t( e9 `: o: D
    send "$newpasswd\r"+ V* m9 h# i9 X" ?$ t$ s3 Q# |
    expect "Retype*assword:"
7 D5 B; K+ A1 f+ w* f5 Y    send "$newpasswd\r"
! I- l7 |0 W1 e1 m2 g" F2 q}
  }/ N% _+ {: r5 o2 B$ q! Z$ |" Aexpect "*#"- _3 W& Z$ |% t2 Z( }$ v- ?; t/ @: C
send "exit\r"
2 M9 f5 Y$ e# L$ M+ R1 }#interact 是否将交互权接过来,如果接过来,则用户这时可进行交互操作
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 01:59 , Processed in 0.013442 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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