Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#
# This script uses John Carter's RExpect module for Ruby; the original is
# available at:
#
# http://www.rubygarden.org/ruby?RExpect
#
require 'pty'
require 'thread'
require 'timeout'
$expect_verbose = false
Thread.abort_on_exception = true
class RExpect
attr_reader :pid
def RExpect.spawn(cmd)
mutex = Mutex.new
mutex.synchronize do
resultResource = ConditionVariable.new
result = nil
Thread.new do
pid = nil
mutex.synchronize do
inf, outf, pid, fileName = PTY.spawn(cmd)
result = RExpect.new( inf, outf, pid, fileName)
resultResource.signal
end
result.inputData
end
resultResource.wait( mutex)
return result
end
end
def log(a)
@log.puts "#{caller(1)[0]}:#{a}" unless @log.nil?
end
def initialize(inf,outf,pid,fileName)
@inf,@outf,@pid,@fileName = inf,outf,pid,fileName
if $expect_verbose then
@log = File.open( "rexpect.log.#{@pid}", "w")
@log.sync = true
else
@log = nil
end
@outf.sync=true
@buffer = ''
@mutex = Mutex.new
@bufferResource = ConditionVariable.new
end
def wait
Process.waitpid(@pid,0)
rescue
end
def kill
kill( "SIGTERM", @pid)
wait
end
def inputData
while true
data = @inf.sysread( 65536)
@mutex.synchronize do
log( "BUFFER:#{@buffer}\nNEWDATA:#{data}" )
@buffer << data
if !@e_pat.nil? && @buffer =~ @e_pat then
@result = [@buffer,$1,$2,$3,$4,$5,$6,$7,$8,$9]
@buffer = $'
log( "Buffer matched#{@e_pat.source}")
@e_pat = nil
@bufferResource.signal
end
end
end
rescue SystemCallError, EOFError => details
log( details)
log( details.backtrace.join("\n"))
@mutex.synchronize do
@bufferResource.signal
end
rescue RuntimeError => details
raise details if details.to_s !~ /Child_changed/
ensure
@log.close
end
def expect(pat,time_out=5)
@result = nil
@mutex.synchronize do
case pat
when String
@e_pat = Regexp.new(Regexp.quote(pat))
when Regexp
@e_pat = pat
end
log( @e_pat.source)
if @buffer =~ @e_pat then
@result = [@buffer,$1,$2,$3,$4,$5,$6,$7,$8,$9]
@buffer = $'
log( "Existing buffer matched#{@e_pat.source}")
@e_pat = nil
return @result
end
timeout( time_out) do
@bufferResource.wait( @mutex)
raise EOFError if @result.nil?
end
end
return @result
end
def puts(str)
log( str)
@outf.puts str
end
end
if __FILE__ == $0
PAUSE = 60
session = RExpect.spawn("ssh -l lyle fxruby.sourceforge.net")
session.expect("-bash-2.05b$", PAUSE)
session.puts("cd fxruby-htdocs/1.2")
session.expect("-bash-2.05b$", PAUSE)
session.puts("tar xzf ../doc.tar.gz")
session.expect("-bash-2.05b$", PAUSE)
session.puts("tar xzf ../examples.tar.gz")
session.expect("-bash-2.05b$", PAUSE)
# session.puts("tar xzf web.tar.gz")
# session.expect("-bash-2.05b$", PAUSE)
session.puts("exit")
end