易陆发现互联网技术论坛

 找回密码
 开始注册
查看: 3904|回复: 1
收起左侧

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

[复制链接]
发表于 2017-12-22 16:37:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?开始注册

x
在linux下写shell脚本是非常有用的,当然,交互式shell脚本更是受到欢迎。expect的简单易用性,使它受到了大家的关注。今天在写expect脚本时遇到一个问题,下面是我对问题的理解:9 O, U; T/ y+ e- r* w& p& v1 }
      先看下面“写法一”:$ h+ I9 V* W/ r) m3 ]2 h0 N% |
.........         % I5 \9 d' ^$ P* q
    expect   "A"   send "AA"' H" t7 v( C6 e) P/ P; J
    expect "B"  send "BB"  P( ~7 R; y% ]# R
....8 S* V% V; l: U* j5 y* j6 V
刚开始,我以为程序会一个个检查,当出现expect的内容时,发送相应内容,当不出现时直接跳到下一个expect。
2 _% N  L% `) O$ P0 W比如: 1.正常交互顺序 : L% m  K* n* Q( C8 b: N. q5 Q+ @
要求输入A内容时,send "AA"
$ E! p- T8 x, r% S, W  A% S要求输入B内容时,send "BB"
  d% {" |& m: q2 ]8 P3 E' `   2.不确定的交互,有些交互在某种情况下出现,有些不出现,下面的例子将举例
8 W: R+ i, F4 L! t                不用输入A了,直接要求输入B内容时,send“BB”
1 ?- V9 E* b1 W& M对于第二种情况,按我以前的理解写法一是可以的,当期望的A交互没出现而交互B出现了,会直接跳过,但事实不是这,它会阻塞,一直等到A交互出现。因此,当有些应用的脚本交互的内容不确定时,写法一将不通用。下面这个例子是我遇到的实例,写一个shell脚本实现远程登录,
6 I8 f0 s- u: }1 h% o     写法二:- o% d. x2 X/ u6 l
                 spawn ssh -l username 192.168.1.18 W, f2 K/ i- w5 U7 g& i
          expect "(yes/no)?"  send "yes"
2 D: X6 w$ v0 ]1 \) h- R   expect "password:" send "AAAA"  L; W5 d8 k, ^" U
          interact5 f. b8 P& ]# j8 F# B, s
         这个脚本是不行的,大家知道,第一次ssh一个远程主机时会出现yes/no的交互,当以后ssh时不会出现,而是只出现第二个,按照上述分析的原因,此脚本第一次时使用时没有问题的,以后再使用时会出现阻塞,因为它一直在等待yes/no的交互,不会跳过去。因此,如果想写一个通用的脚本,就要在交互要求不确定时,跳过一些,最终的写法如下:8 x  u$ v0 i, Q; A) X: s
写法三:
7 w7 P8 S7 C5 d9 ^$ B9 ^       spawn ssh -l username 192.168.1.1
- x2 g6 W* n" s+ f: q' |' a0 ^expect{
6 P) l( g" v8 `# P4 v$ H, q "(yes/no)?" { send "yes"; exp_continue}
, T# c' B, G) ^! m" C "password:" {send "AAAA"}
9 F/ t; `( e; d$ o4 X6 {         }
# S5 H* d) x0 {6 T+ V- D0 ?: H interact. \' N. [+ m1 U$ `: t5 F
这里可以理解为expect块,当出现yes/no交互式当然send相应内容,当没有出现,而是出现password时也不会阻塞,而是执行相应的send。理解时可以联想case语句块。
 楼主| 发表于 2017-12-22 17:12:25 | 显示全部楼层
echo | ssh -l root passwd --stdin7 W" E# ?2 ~! ]6 F6 ^& ^* `, v" H% L
echo "newpass" | ssh -l root 10.11.103.151 passwd --stdin dewang
# R- O; C, \: y8 E% Wroot@10.11.103.151's password:
/ n+ J* u9 |2 ~9 i* F/ }0 qChanging password for user dewang.- q2 O7 h. E# w( `( \8 D2 d
passwd: all authentication tokens updated successfully.( G8 i5 A4 K* D$ K! j8 a' i( p
, j$ r$ i2 O9 o" t4 s

5 @! T, T. U5 m) n6 V% T#!/usr/bin/expect( F1 |$ z" w5 N7 T6 l
#@brief to change user password by ssh remote machine
; h* C" i$ |- q+ J) w) N9 J+ @( ]7 ]  Q# [. z
proc usage {funcname} {/ y+ R! Z) e* O; ]2 i
    puts "Usage: "
) X  y! Y; \* t: {7 i    puts "    $funcname -user "% e: U7 x: d! `" W2 c- J
    puts "    $funcname -root "7 x. p4 \- B+ _8 {' C
}   
( U6 ^# D% h/ Y% o! b0 k+ a- v, C% p
# check param! v% A9 x$ p' ^# H. b
if { $argc != 5 } {3 S% F) T+ |" D# i5 c' O1 D
    usage $argv0
+ a  P, F5 }- S    exit 1
0 |5 i: X* w8 e# w4 |1 d, _}
) p* a5 w) p! j( E  Q/ M6 H- O+ {
# get param& V* K9 h: D1 C# D+ Q' f7 N
set host [lindex $argv 0]& C, J7 L4 C. d3 J  Q
set username [lindex $argv 1]1 n3 @. }- v3 `
set newpasswd [lindex $argv 2]. D5 `) \7 A: E! j6 b4 K! x
set loginname "root"
6 N" [8 z, [) p- Aif { [string compare [lindex $argv 3] "-user"] == 0 } {1 J# z: V9 T+ x/ S
    set loginname $username. f# f. t: o3 [8 k; I
}
, k- l; n2 r2 W) Aset passwd [lindex $argv 4]
) P% V" d' G7 v/ L" q+ Oputs "$host $username $newpasswd $loginname $passwd"
) ~: A$ E* c4 y; ]2 V7 a2 A/ ?& D. Q6 \$ A
spawn ssh -l $loginname $host( H. g& W9 r8 {6 ]' z, G3 c
expect {2 C: b1 l) {8 m& i& q
"*(yes/no)*" { send "yes\r"; set sshkey 1 }  }9 V0 n* o# |
"*assword:*" { send "$passwd\r"; set sshkey 0 }
3 c; J9 @8 J& H$ b" _if sshkey == 1 {8 Z* L7 h, V% N5 c0 d# i  A
    expect "*password:*"- b, L4 D4 j/ C  |) I
    send "$passwd\r"0 R' Q" Q& p6 u
}; `3 V: R' D+ ~1 t2 w
}
, c# I+ W# `$ L+ H% Qexpect "*#"
& |7 g% Y* E4 ]5 T; i- ?# V) v0 G' [: n4 J7 M2 ^/ h. x) s9 S/ b  R- L
if { [string compare $loginname "root"] == 0 } {
/ w+ R9 C4 K7 `2 m* O) |  O    #send "echo \"$username:$newpasswd\" | chpasswd\r"1 A* i/ q6 |1 w* F% P: t' I
    send "echo \"$newpasswd\" | passwd --stdin \"$username\"\r"5 ?4 J" c5 R9 y  L" [  O
} else {5 g/ F: N7 N+ W0 U$ P  U+ P( M
    send "passwd\r"
9 H1 S4 f4 r3 p    expect {" f; w) _. _& J6 w+ k1 T
    "*current*assword:" {send "$passwd\r"}3 d# |' E9 }& Y( s
    "passwd: Authentication token manipulation error" {exit}3 \! x7 ?  ^3 {* o6 T
    }7 y$ r  S% L. i8 x
    expect "New*assword:"* \; T; ?1 D. A, A$ w& }. j
    send "$newpasswd\r"0 \! M: i% L% Z( m( O, h* P+ L
    expect "Retype*assword:"# M$ M' u" M3 ?, _" q# U+ G- b. N& `
    send "$newpasswd\r"
9 A' f: Y& T$ D}' ?9 f  U( Y' h, N
expect "*#") B! _" P" M; H0 p
send "exit\r"- D: c8 S& N' U# J, R2 Y
#interact 是否将交互权接过来,如果接过来,则用户这时可进行交互操作
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

站长推荐上一条 /4 下一条

北京云银创陇科技有限公司以云计算运维,代码开发

QQ|返回首页|Archiver|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )点击这里给我发消息

GMT+8, 2026-4-9 01:06 , Processed in 0.076338 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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