63
|
1 """Pexpect is a Python module for spawning child applications;
|
|
2 controlling them; and responding to expected patterns in their output.
|
|
3 Pexpect can be used for automating interactive applications such as
|
|
4 ssh, ftp, passwd, telnet, etc. It can be used to a automate setup scripts
|
|
5 for duplicating software package installations on different servers.
|
|
6 It can be used for automated software testing. Pexpect is in the spirit of
|
|
7 Don Libes' Expect, but Pexpect is pure Python. Other Expect-like
|
|
8 modules for Python require TCL and Expect or require C extensions to
|
|
9 be compiled. Pexpect does not use C, Expect, or TCL extensions. It
|
|
10 should work on any platform that supports the standard Python pty
|
|
11 module. The Pexpect interface focuses on ease of use so that simple
|
|
12 tasks are easy.
|
|
13
|
|
14 There are two main interfaces to Pexpect. You can call the function:
|
|
15 pexpect.run()
|
|
16 to execute a command and return the output.
|
|
17 Do no use this on interactive commands that expect input.
|
|
18 This is a handy replacment for os.system().
|
|
19 The more useful interface is the class:
|
|
20 pexpect.spawn()
|
|
21 This creates a spawn instance. This will start the command that you specify.
|
|
22 You can then interact with the child command through the spawn instance.
|
|
23 Most commands, including ssh, cannot tell that they are being run inside
|
|
24 of a script. This works even for commands that ask for passwords or
|
|
25 other input outside of the normal stdio streams.
|
|
26
|
|
27 Pexpect is Open Source, Free, and all that good stuff.
|
|
28 License: Python Software Foundation License
|
|
29 http://www.opensource.org/licenses/PythonSoftFoundation.html
|
|
30
|
|
31 Noah Spurrier
|
|
32 Richard Holden
|
|
33 Marco Molteni
|
|
34 Kimberley Burchett
|
|
35 Robert Stone
|
|
36 Mike Snitzer
|
|
37 Marti Raudsepp
|
|
38 Matt <matt (*) corvil.com>
|
|
39 Hartmut Goebel
|
|
40 Chad Schroeder
|
|
41 Erick Tryzelaar
|
|
42 Dave Kirby
|
|
43 Ids vander Molen
|
|
44 George Todd
|
|
45 Noel Taylor
|
|
46 Nicolas D. Cesar
|
|
47 (Let me know if I forgot anyone.)
|
|
48
|
|
49 $Revision: 1.1.1.1 $
|
|
50 $Date: 2006/04/01 06:03:29 $
|
|
51 """
|
|
52
|
|
53 try:
|
|
54 import os, sys, time
|
|
55 import select
|
|
56 import string
|
|
57 import re
|
|
58 import struct
|
|
59 import resource
|
|
60 import types
|
|
61 import pty
|
|
62 import tty
|
|
63 import termios
|
|
64 import fcntl
|
|
65 import errno
|
|
66 import traceback
|
|
67 import signal
|
|
68 except ImportError, e:
|
|
69 raise ImportError (str(e) + """
|
|
70 A critical module was not found. Probably this operating system does not support it.
|
|
71 Pexpect is intended for UNIX-like operating systems.""")
|
|
72
|
|
73 __version__ = '2.0'
|
|
74 __revision__ = '$Revision: 1.1.1.1 $'
|
|
75 __all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'run', 'which', 'split_command_line',
|
|
76 '__version__', '__revision__']
|
|
77
|
|
78 # Exception classes used by this module.
|
|
79 class ExceptionPexpect(Exception):
|
|
80 """Base class for all exceptions raised by this module.
|
|
81 """
|
|
82 def __init__(self, value):
|
|
83 self.value = value
|
|
84 def __str__(self):
|
|
85 return str(self.value)
|
|
86 def get_trace(self):
|
|
87 """This returns an abbreviated stack trace with lines that only concern the caller.
|
|
88 In other words, the stack trace inside the Pexpect module is not included.
|
|
89 """
|
|
90 tblist = traceback.extract_tb(sys.exc_info()[2])
|
|
91 tblist = filter(self.__filter_not_pexpect, tblist)
|
|
92 tblist = traceback.format_list(tblist)
|
|
93 return ''.join(tblist)
|
|
94 def __filter_not_pexpect(self, trace_list_item):
|
|
95 if trace_list_item[0].find('pexpect.py') == -1:
|
|
96 return 1
|
|
97 else:
|
|
98 return 0
|
|
99 class EOF(ExceptionPexpect):
|
|
100 """Raised when EOF is read from a child.
|
|
101 """
|
|
102 class TIMEOUT(ExceptionPexpect):
|
|
103 """Raised when a read time exceeds the timeout.
|
|
104 """
|
|
105 ##class TIMEOUT_PATTERN(TIMEOUT):
|
|
106 ## """Raised when the pattern match time exceeds the timeout.
|
|
107 ## This is different than a read TIMEOUT because the child process may
|
|
108 ## give output, thus never give a TIMEOUT, but the output
|
|
109 ## may never match a pattern.
|
|
110 ## """
|
|
111 ##class MAXBUFFER(ExceptionPexpect):
|
|
112 ## """Raised when a scan buffer fills before matching an expected pattern."""
|
|
113
|
|
114 def run (command, timeout=-1, withexitstatus=0, events=None, extra_args=None):
|
|
115 """This function runs the given command; waits for it to finish;
|
|
116 then returns all output as a string. STDERR is included in output.
|
|
117 If the full path to the command is not given then the path is searched.
|
|
118
|
|
119 Note that lines are terminated by CR/LF (\\r\\n) combination
|
|
120 even on UNIX-like systems because this is the standard for pseudo ttys.
|
|
121 If you set withexitstatus to true, then run will return a tuple of
|
|
122 (command_output, exitstatus). If withexitstatus is false then this
|
|
123 returns just command_output.
|
|
124
|
|
125 Examples:
|
|
126 Start the apache daemon on the local machine:
|
|
127 from pexpect import *
|
|
128 run ("/usr/local/apache/bin/apachectl start")
|
|
129 Check in a file using SVN:
|
|
130 from pexpect import *
|
|
131 run ("svn ci -m 'automatic commit' my_file.py")
|
|
132 Run a command and capture exit status:
|
|
133 from pexpect import *
|
|
134 (command_output, exitstatus) = run ('ls -l /bin', withexitstatus=1)
|
|
135
|
|
136 Tricky Examples:
|
|
137 The following will run SSH and execute 'ls -l' on the remote machine.
|
|
138 The password 'secret' will be sent if the '(?i)password' pattern is ever seen.
|
|
139 run ("ssh username@machine.example.com 'ls -l'", events={'(?i)password':'secret\n'})
|
|
140
|
|
141 This will start mencoder to rip a video from DVD. This will also display
|
|
142 progress ticks every 5 seconds as it runs.
|
|
143 from pexpect import *
|
|
144 def print_ticks(d):
|
|
145 print d['event_count'],
|
|
146 run ("mencoder dvd://1 -o video.avi -oac copy -ovc copy", events={TIMEOUT:print_ticks}, timeout=5)
|
|
147
|
|
148 The 'events' argument should be a dictionary of patterns and responses.
|
|
149 Whenever one of the patterns is seen in the command out
|
|
150 run() will send the associated response string. Note that you should
|
|
151 put newlines in your string if Enter is necessary.
|
|
152 The responses may also contain callback functions.
|
|
153 Any callback is function that takes a dictionary as an argument.
|
|
154 The dictionary contains all the locals from the run() function, so
|
|
155 you can access the child spawn object or any other variable defined
|
|
156 in run() (event_count, child, and extra_args are the most useful).
|
|
157 A callback may return True to stop the current run process otherwise
|
|
158 run() continues until the next event.
|
|
159 A callback may also return a string which will be sent to the child.
|
|
160 'extra_args' is not used by directly run(). It provides a way to pass data to
|
|
161 a callback function through run() through the locals dictionary passed to a callback.
|
|
162 """
|
|
163 if timeout == -1:
|
|
164 child = spawn(command, maxread=2000)
|
|
165 else:
|
|
166 child = spawn(command, timeout=timeout, maxread=2000)
|
|
167 if events is not None:
|
|
168 patterns = events.keys()
|
|
169 responses = events.values()
|
|
170 else:
|
|
171 patterns=None # We assume that EOF or TIMEOUT will save us.
|
|
172 responses=None
|
|
173 child_result_list = []
|
|
174 event_count = 0
|
|
175 while 1:
|
|
176 try:
|
|
177 index = child.expect (patterns)
|
|
178 if type(child.after) is types.StringType:
|
|
179 child_result_list.append(child.before + child.after)
|
|
180 else: # child.after may have been a TIMEOUT or EOF, so don't cat those.
|
|
181 child_result_list.append(child.before)
|
|
182 if type(responses[index]) is types.StringType:
|
|
183 child.send(responses[index])
|
|
184 elif type(responses[index]) is types.FunctionType:
|
|
185 callback_result = responses[index](locals())
|
|
186 sys.stdout.flush()
|
|
187 if type(callback_result) is types.StringType:
|
|
188 child.send(callback_result)
|
|
189 elif callback_result:
|
|
190 break
|
|
191 else:
|
|
192 raise TypeError ('The callback must be a string or function type.')
|
|
193 event_count = event_count + 1
|
|
194 except TIMEOUT, e:
|
|
195 child_result_list.append(child.before)
|
|
196 break
|
|
197 except EOF, e:
|
|
198 child_result_list.append(child.before)
|
|
199 break
|
|
200 child_result = ''.join(child_result_list)
|
|
201 if withexitstatus:
|
|
202 child.close()
|
|
203 return (child_result, child.exitstatus)
|
|
204 else:
|
|
205 return child_result
|
|
206
|
|
207 class spawn:
|
|
208 """This is the main class interface for Pexpect.
|
|
209 Use this class to start and control child applications.
|
|
210 """
|
|
211
|
|
212 def __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None):
|
|
213 """This is the constructor. The command parameter may be a string
|
|
214 that includes a command and any arguments to the command. For example:
|
|
215 p = pexpect.spawn ('/usr/bin/ftp')
|
|
216 p = pexpect.spawn ('/usr/bin/ssh user@example.com')
|
|
217 p = pexpect.spawn ('ls -latr /tmp')
|
|
218 You may also construct it with a list of arguments like so:
|
|
219 p = pexpect.spawn ('/usr/bin/ftp', [])
|
|
220 p = pexpect.spawn ('/usr/bin/ssh', ['user@example.com'])
|
|
221 p = pexpect.spawn ('ls', ['-latr', '/tmp'])
|
|
222 After this the child application will be created and
|
|
223 will be ready to talk to. For normal use, see expect() and
|
|
224 send() and sendline().
|
|
225
|
|
226 The maxread attribute sets the read buffer size.
|
|
227 This is maximum number of bytes that Pexpect will try to read from a TTY at one time.
|
|
228 The default buffer size is 1 (unbuffered). Setting this value higher
|
|
229 will help performance in cases where large amounts of output are read back from the child.
|
|
230 This feature is useful in conjunction with searchwindowsize.
|
|
231
|
|
232 The searchwindowsize attribute sets the how far back in
|
|
233 the incomming seach buffer Pexpect will search for pattern matches.
|
|
234 Every time Pexpect reads some data from the child it will append the data to
|
|
235 the incomming buffer. The default is to search from the beginning of the
|
|
236 imcomming buffer each time new data is read from the child.
|
|
237 But this is very inefficient if you are running a command that
|
|
238 generates a large amount of data where you want to match
|
|
239 The searchwindowsize does not effect the size of the incomming data buffer.
|
|
240 You will still have access to the full buffer after expect() returns.
|
|
241
|
|
242 The logfile member turns on or off logging.
|
|
243 All input and output will be copied to the given file object.
|
|
244 Set logfile to None to stop logging. This is the default.
|
|
245 Set logfile to sys.stdout to echo everything to standard output.
|
|
246 The logfile is flushed after each write.
|
|
247 Example 1:
|
|
248 child = pexpect.spawn('some_command')
|
|
249 fout = file('mylog.txt','w')
|
|
250 child.logfile = fout
|
|
251 Example 2:
|
|
252 child = pexpect.spawn('some_command')
|
|
253 child.logfile = sys.stdout
|
|
254
|
|
255 The delaybeforesend helps overcome weird behavior that many users were experiencing.
|
|
256 The typical problem was that a user would expect() a "Password:" prompt and
|
|
257 then immediately call sendline() to send the password. The user would then
|
|
258 see that their password was echoed back to them. Of course, passwords don't
|
|
259 normally echo. The problem is caused by the fact that most applications
|
|
260 print out the "Password" prompt and then turn off stdin echo, but if you
|
|
261 send your password before the application turned off echo, then you get
|
|
262 your password echoed. Normally this wouldn't be a problem when interacting
|
|
263 with a human at a real heyboard. If you introduce a slight delay just before
|
|
264 writing then this seems to clear up the problem. This was such a common problem
|
|
265 for many users that I decided that the default pexpect behavior
|
|
266 should be to sleep just before writing to the child application.
|
|
267 1/10th of a second (100 ms) seems to be enough to clear up the problem.
|
|
268 You can set delaybeforesend to 0 to return to the old behavior.
|
|
269
|
|
270 Note that spawn is clever about finding commands on your path.
|
|
271 It uses the same logic that "which" uses to find executables.
|
|
272
|
|
273 If you wish to get the exit status of the child you must call
|
|
274 the close() method. The exit or signal status of the child will be
|
|
275 stored in self.exitstatus or self.signalstatus.
|
|
276 If the child exited normally then exitstatus will store the exit return code and
|
|
277 signalstatus will be None.
|
|
278 If the child was terminated abnormally with a signal then signalstatus will store
|
|
279 the signal value and exitstatus will be None.
|
|
280 If you need more detail you can also read the self.status member which stores
|
|
281 the status returned by os.waitpid. You can interpret this using
|
|
282 os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG.
|
|
283 """
|
|
284 self.STDIN_FILENO = pty.STDIN_FILENO
|
|
285 self.STDOUT_FILENO = pty.STDOUT_FILENO
|
|
286 self.STDERR_FILENO = pty.STDERR_FILENO
|
|
287 self.stdin = sys.stdin
|
|
288 self.stdout = sys.stdout
|
|
289 self.stderr = sys.stderr
|
|
290
|
|
291 self.patterns = None
|
|
292 self.before = None
|
|
293 self.after = None
|
|
294 self.match = None
|
|
295 self.match_index = None
|
|
296 self.terminated = 1
|
|
297 self.exitstatus = None
|
|
298 self.signalstatus = None
|
|
299 self.status = None
|
|
300 self.flag_eof = 0
|
|
301 self.pid = None
|
|
302 self.child_fd = -1 # initially closed
|
|
303 self.timeout = timeout
|
|
304 self.delimiter = EOF
|
|
305 self.logfile = logfile
|
|
306 self.maxread = maxread # Max bytes to read at one time into buffer.
|
|
307 self.buffer = '' # This is the read buffer. See maxread.
|
|
308 self.searchwindowsize = searchwindowsize # Anything before searchwindowsize point is preserved, but not searched.
|
|
309 self.delaybeforesend = 0.1 # Sets sleep time used just before sending data to child.
|
|
310 self.softspace = 0 # File-like object.
|
|
311 self.name = '<' + repr(self) + '>' # File-like object.
|
|
312 self.encoding = None # File-like object.
|
|
313 self.closed = 1 # File-like object.
|
|
314
|
|
315 if type (args) != type([]):
|
|
316 raise TypeError ('The second argument, args, must be a list.')
|
|
317
|
|
318 if args == []:
|
|
319 self.args = split_command_line(command)
|
|
320 self.command = self.args[0]
|
|
321 else:
|
|
322 self.args = args[:] # work with a copy
|
|
323 self.args.insert (0, command)
|
|
324 self.command = command
|
|
325
|
|
326 command_with_path = which(self.command)
|
|
327 if command_with_path == None:
|
|
328 raise ExceptionPexpect ('The command was not found or was not executable: %s.' % self.command)
|
|
329 self.command = command_with_path
|
|
330 self.args[0] = self.command
|
|
331
|
|
332 self.name = '<' + ' '.join (self.args) + '>'
|
|
333 self.__spawn()
|
|
334
|
|
335 def __del__(self):
|
|
336 """This makes sure that no system resources are left open.
|
|
337 Python only garbage collects Python objects. OS file descriptors
|
|
338 are not Python objects, so they must be handled explicitly.
|
|
339 If the child file descriptor was opened outside of this class
|
|
340 (passed to the constructor) then this does not close it.
|
|
341 """
|
|
342 if self.closed:
|
|
343 return
|
|
344 self.close()
|
|
345
|
|
346 def __str__(self):
|
|
347 """This returns the current state of the pexpect object as a string.
|
|
348 """
|
|
349 s = []
|
|
350 s.append(repr(self))
|
|
351 s.append('version: ' + __version__ + ' (' + __revision__ + ')')
|
|
352 s.append('command: ' + str(self.command))
|
|
353 s.append('args: ' + str(self.args))
|
|
354 if self.patterns is None:
|
|
355 s.append('patterns: None')
|
|
356 else:
|
|
357 s.append('patterns:')
|
|
358 for p in self.patterns:
|
|
359 if type(p) is type(re.compile('')):
|
|
360 s.append(' ' + str(p.pattern))
|
|
361 else:
|
|
362 s.append(' ' + str(p))
|
|
363 s.append('buffer (last 100 chars): ' + str(self.buffer)[-100:])
|
|
364 s.append('before (last 100 chars): ' + str(self.before)[-100:])
|
|
365 s.append('after: ' + str(self.after))
|
|
366 s.append('match: ' + str(self.match))
|
|
367 s.append('match_index: ' + str(self.match_index))
|
|
368 s.append('exitstatus: ' + str(self.exitstatus))
|
|
369 s.append('flag_eof: ' + str(self.flag_eof))
|
|
370 s.append('pid: ' + str(self.pid))
|
|
371 s.append('child_fd: ' + str(self.child_fd))
|
|
372 s.append('timeout: ' + str(self.timeout))
|
|
373 s.append('delimiter: ' + str(self.delimiter))
|
|
374 s.append('logfile: ' + str(self.logfile))
|
|
375 s.append('maxread: ' + str(self.maxread))
|
|
376 s.append('searchwindowsize: ' + str(self.searchwindowsize))
|
|
377 s.append('delaybeforesend: ' + str(self.delaybeforesend))
|
|
378 return '\n'.join(s)
|
|
379
|
|
380 def __spawn(self):
|
|
381 """This starts the given command in a child process.
|
|
382 This does all the fork/exec type of stuff for a pty.
|
|
383 This is called by __init__.
|
|
384 """
|
|
385 # The pid and child_fd of this object get set by this method.
|
|
386 # Note that it is difficult for this method to fail.
|
|
387 # You cannot detect if the child process cannot start.
|
|
388 # So the only way you can tell if the child process started
|
|
389 # or not is to try to read from the file descriptor. If you get
|
|
390 # EOF immediately then it means that the child is already dead.
|
|
391 # That may not necessarily be bad because you may haved spawned a child
|
|
392 # that performs some task; creates no stdout output; and then dies.
|
|
393
|
|
394 assert self.pid == None, 'The pid member should be None.'
|
|
395 assert self.command != None, 'The command member should not be None.'
|
|
396
|
|
397 try:
|
|
398 self.pid, self.child_fd = pty.fork()
|
|
399 except OSError, e:
|
|
400 raise ExceptionPexpect('Pexpect: pty.fork() failed: ' + str(e))
|
|
401
|
|
402 if self.pid == 0: # Child
|
|
403 try: # Some platforms do not like setwinsize (Cygwin).
|
|
404 self.child_fd = sys.stdout.fileno() # used by setwinsize()
|
|
405 self.setwinsize(24, 80)
|
|
406 except:
|
|
407 pass
|
|
408 # Do not allow child to inherit open file descriptors from parent.
|
|
409 max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0]
|
|
410 for i in range (3, max_fd):
|
|
411 try:
|
|
412 os.close (i)
|
|
413 except OSError:
|
|
414 pass
|
|
415
|
|
416 # I don't know why this works, but ignoring SIGHUP fixes a
|
|
417 # problem when trying to start a Java daemon with sudo
|
|
418 # (specifically, Tomcat).
|
|
419 signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
|
420
|
|
421 os.execv(self.command, self.args)
|
|
422
|
|
423 # Parent
|
|
424 self.terminated = 0
|
|
425 self.closed = 0
|
|
426
|
|
427 def fileno (self): # File-like object.
|
|
428 """This returns the file descriptor of the pty for the child.
|
|
429 """
|
|
430 return self.child_fd
|
|
431
|
|
432 def close (self, force=0): # File-like object.
|
|
433 """This closes the connection with the child application.
|
|
434 Note that calling close() more than once is valid.
|
|
435 This emulates standard Python behavior with files.
|
|
436 Set force to 1 if you want to make sure that the child is terminated
|
|
437 (SIGKILL is sent if the child ignores SIGHUP and SIGINT).
|
|
438 """
|
|
439 if self.child_fd != -1:
|
|
440 self.flush()
|
|
441 os.close (self.child_fd)
|
|
442 self.child_fd = -1
|
|
443 self.closed = 1
|
|
444 time.sleep(0.1) # Give kernel time to update process status.
|
|
445 if self.isalive():
|
|
446 if not self.terminate(force):
|
|
447 raise ExceptionPexpect ('close() could not terminate the child using terminate()')
|
|
448
|
|
449 def flush (self): # File-like object.
|
|
450 """This does nothing. It is here to support the interface for a File-like object.
|
|
451 """
|
|
452 pass
|
|
453
|
|
454 def isatty (self): # File-like object.
|
|
455 """This returns 1 if the file descriptor is open and connected to a tty(-like) device, else 0.
|
|
456 """
|
|
457 return os.isatty(self.child_fd)
|
|
458
|
|
459 def setecho (self, on):
|
|
460 """This sets the terminal echo mode on or off.
|
|
461 Note that anything the child sent before the echo will be lost, so
|
|
462 you should be sure that your input buffer is empty before you setecho.
|
|
463 For example, the following will work as expected.
|
|
464 p = pexpect.spawn('cat')
|
|
465 p.sendline ('1234') # We will see this twice (once from tty echo and again from cat).
|
|
466 p.expect (['1234'])
|
|
467 p.expect (['1234'])
|
|
468 p.setecho(0) # Turn off tty echo
|
|
469 p.sendline ('abcd') # We will set this only once (echoed by cat).
|
|
470 p.sendline ('wxyz') # We will set this only once (echoed by cat)
|
|
471 p.expect (['abcd'])
|
|
472 p.expect (['wxyz'])
|
|
473 The following WILL NOT WORK because the lines sent before the setecho
|
|
474 will be lost:
|
|
475 p = pexpect.spawn('cat')
|
|
476 p.sendline ('1234') # We will see this twice (once from tty echo and again from cat).
|
|
477 p.setecho(0) # Turn off tty echo
|
|
478 p.sendline ('abcd') # We will set this only once (echoed by cat).
|
|
479 p.sendline ('wxyz') # We will set this only once (echoed by cat)
|
|
480 p.expect (['1234'])
|
|
481 p.expect (['1234'])
|
|
482 p.expect (['abcd'])
|
|
483 p.expect (['wxyz'])
|
|
484 """
|
|
485 self.child_fd
|
|
486 new = termios.tcgetattr(self.child_fd)
|
|
487 if on:
|
|
488 new[3] = new[3] | termios.ECHO
|
|
489 else:
|
|
490 new[3] = new[3] & ~termios.ECHO
|
|
491 # I tried TCSADRAIN and TCSAFLUSH, but these were inconsistent
|
|
492 # and blocked on some platforms. TCSADRAIN is probably ideal if it worked.
|
|
493 termios.tcsetattr(self.child_fd, termios.TCSANOW, new)
|
|
494
|
|
495 def read_nonblocking (self, size = 1, timeout = -1):
|
|
496 """This reads at most size characters from the child application.
|
|
497 It includes a timeout. If the read does not complete within the
|
|
498 timeout period then a TIMEOUT exception is raised.
|
|
499 If the end of file is read then an EOF exception will be raised.
|
|
500 If a log file was set using setlog() then all data will
|
|
501 also be written to the log file.
|
|
502
|
|
503 If timeout==None then the read may block indefinitely.
|
|
504 If timeout==-1 then the self.timeout value is used.
|
|
505 If timeout==0 then the child is polled and
|
|
506 if there was no data immediately ready then this will raise a TIMEOUT exception.
|
|
507
|
|
508 The "timeout" refers only to the amount of time to read at least one character.
|
|
509 This is not effected by the 'size' parameter, so if you call
|
|
510 read_nonblocking(size=100, timeout=30) and only one character is
|
|
511 available right away then one character will be returned immediately.
|
|
512 It will not wait for 30 seconds for another 99 characters to come in.
|
|
513
|
|
514 This is a wrapper around os.read().
|
|
515 It uses select.select() to implement a timeout.
|
|
516 """
|
|
517 if self.child_fd == -1:
|
|
518 raise ValueError ('I/O operation on closed file in read_nonblocking().')
|
|
519
|
|
520 if timeout == -1:
|
|
521 timeout = self.timeout
|
|
522
|
|
523 # Note that some systems such as Solaris do not give an EOF when
|
|
524 # the child dies. In fact, you can still try to read
|
|
525 # from the child_fd -- it will block forever or until TIMEOUT.
|
|
526 # For this case, I test isalive() before doing any reading.
|
|
527 # If isalive() is false, then I pretend that this is the same as EOF.
|
|
528 if not self.isalive():
|
|
529 r, w, e = select.select([self.child_fd], [], [], 0) # timeout of 0 means "poll"
|
|
530 if not r:
|
|
531 self.flag_eof = 1
|
|
532 raise EOF ('End Of File (EOF) in read_nonblocking(). Braindead platform.')
|
|
533 elif sys.platform.lower().find('irix') >= 0:
|
|
534 # This is a hack for Irix. It seems that Irix requires a long delay before checking isalive.
|
|
535 # This adds a 2 second delay, but only when the child is terminated
|
|
536 r, w, e = select.select([self.child_fd], [], [], 2)
|
|
537 if not r and not self.isalive():
|
|
538 self.flag_eof = 1
|
|
539 raise EOF ('End Of File (EOF) in read_nonblocking(). Pokey platform.')
|
|
540
|
|
541 r, w, e = select.select([self.child_fd], [], [], timeout)
|
|
542 if not r:
|
|
543 if not self.isalive():
|
|
544 # Some platforms, such as Irix, will claim that their processes are alive;
|
|
545 # then timeout on the select; and then finally admit that they are not alive.
|
|
546 self.flag_eof = 1
|
|
547 raise EOF ('End of File (EOF) in read_nonblocking(). Very pokey platform.')
|
|
548 else:
|
|
549 raise TIMEOUT ('Timeout exceeded in read_nonblocking().')
|
|
550
|
|
551 if self.child_fd in r:
|
|
552 try:
|
|
553 s = os.read(self.child_fd, size)
|
|
554 except OSError, e: # Linux does this
|
|
555 self.flag_eof = 1
|
|
556 raise EOF ('End Of File (EOF) in read_nonblocking(). Exception style platform.')
|
|
557 if s == '': # BSD style
|
|
558 self.flag_eof = 1
|
|
559 raise EOF ('End Of File (EOF) in read_nonblocking(). Empty string style platform.')
|
|
560
|
|
561 if self.logfile != None:
|
|
562 self.logfile.write (s)
|
|
563 self.logfile.flush()
|
|
564
|
|
565 return s
|
|
566
|
|
567 raise ExceptionPexpect ('Reached an unexpected state in read_nonblocking().')
|
|
568
|
|
569 def read (self, size = -1): # File-like object.
|
|
570 """This reads at most "size" bytes from the file
|
|
571 (less if the read hits EOF before obtaining size bytes).
|
|
572 If the size argument is negative or omitted,
|
|
573 read all data until EOF is reached.
|
|
574 The bytes are returned as a string object.
|
|
575 An empty string is returned when EOF is encountered immediately.
|
|
576 """
|
|
577 if size == 0:
|
|
578 return ''
|
|
579 if size < 0:
|
|
580 self.expect (self.delimiter) # delimiter default is EOF
|
|
581 return self.before
|
|
582
|
|
583 # I could have done this more directly by not using expect(), but
|
|
584 # I deliberately decided to couple read() to expect() so that
|
|
585 # I would catch any bugs early and ensure consistant behavior.
|
|
586 # It's a little less efficient, but there is less for me to
|
|
587 # worry about if I have to later modify read() or expect().
|
|
588 # Note, it's OK if size==-1 in the regex. That just means it
|
|
589 # will never match anything in which case we stop only on EOF.
|
|
590 cre = re.compile('.{%d}' % size, re.DOTALL)
|
|
591 index = self.expect ([cre, self.delimiter]) # delimiter default is EOF
|
|
592 if index == 0:
|
|
593 return self.after ### self.before should be ''. Should I assert this?
|
|
594 return self.before
|
|
595
|
|
596 def readline (self, size = -1): # File-like object.
|
|
597 """This reads and returns one entire line. A trailing newline is kept in
|
|
598 the string, but may be absent when a file ends with an incomplete line.
|
|
599 Note: This readline() looks for a \\r\\n pair even on UNIX because this is
|
|
600 what the pseudo tty device returns. So contrary to what you may be used to
|
|
601 you will receive a newline as \\r\\n.
|
|
602 An empty string is returned when EOF is hit immediately.
|
|
603 Currently, the size agument is mostly ignored, so this behavior is not
|
|
604 standard for a file-like object. If size is 0 then an empty string is returned.
|
|
605 """
|
|
606 if size == 0:
|
|
607 return ''
|
|
608 index = self.expect (['\r\n', self.delimiter]) # delimiter default is EOF
|
|
609 if index == 0:
|
|
610 return self.before + '\r\n'
|
|
611 else:
|
|
612 return self.before
|
|
613
|
|
614 def __iter__ (self): # File-like object.
|
|
615 """This is to support interators over a file-like object.
|
|
616 """
|
|
617 return self
|
|
618
|
|
619 def next (self): # File-like object.
|
|
620 """This is to support iterators over a file-like object.
|
|
621 """
|
|
622 result = self.readline()
|
|
623 if result == "":
|
|
624 raise StopIteration
|
|
625 return result
|
|
626
|
|
627 def readlines (self, sizehint = -1): # File-like object.
|
|
628 """This reads until EOF using readline() and returns a list containing
|
|
629 the lines thus read. The optional "sizehint" argument is ignored.
|
|
630 """
|
|
631 lines = []
|
|
632 while 1:
|
|
633 line = self.readline()
|
|
634 if not line:
|
|
635 break
|
|
636 lines.append(line)
|
|
637 return lines
|
|
638
|
|
639 def write(self, str): # File-like object.
|
|
640 """This is similar to send() except that there is no return value.
|
|
641 """
|
|
642 self.send (str)
|
|
643
|
|
644 def writelines (self, sequence): # File-like object.
|
|
645 """This calls write() for each element in the sequence.
|
|
646 The sequence can be any iterable object producing strings,
|
|
647 typically a list of strings. This does not add line separators
|
|
648 There is no return value.
|
|
649 """
|
|
650 for str in sequence:
|
|
651 self.write (str)
|
|
652
|
|
653 def send(self, str):
|
|
654 """This sends a string to the child process.
|
|
655 This returns the number of bytes written.
|
|
656 If a log file was set then the data is also written to the log.
|
|
657 """
|
|
658 time.sleep(self.delaybeforesend)
|
|
659 if self.logfile != None:
|
|
660 self.logfile.write (str)
|
|
661 self.logfile.flush()
|
|
662 c = os.write(self.child_fd, str)
|
|
663 return c
|
|
664
|
|
665 def sendline(self, str=''):
|
|
666 """This is like send(), but it adds a line feed (os.linesep).
|
|
667 This returns the number of bytes written.
|
|
668 """
|
|
669 n = self.send(str)
|
|
670 n = n + self.send (os.linesep)
|
|
671 return n
|
|
672
|
|
673 def sendeof(self):
|
|
674 """This sends an EOF to the child.
|
|
675 This sends a character which causes the pending parent output
|
|
676 buffer to be sent to the waiting child program without
|
|
677 waiting for end-of-line. If it is the first character of the
|
|
678 line, the read() in the user program returns 0, which
|
|
679 signifies end-of-file. This means to work as expected
|
|
680 a sendeof() has to be called at the begining of a line.
|
|
681 This method does not send a newline. It is the responsibility
|
|
682 of the caller to ensure the eof is sent at the beginning of a line.
|
|
683 """
|
|
684 ### Hmmm... how do I send an EOF?
|
|
685 ###C if ((m = write(pty, *buf, p - *buf)) < 0)
|
|
686 ###C return (errno == EWOULDBLOCK) ? n : -1;
|
|
687 fd = sys.stdin.fileno()
|
|
688 old = termios.tcgetattr(fd) # remember current state
|
|
689 new = termios.tcgetattr(fd)
|
|
690 new[3] = new[3] | termios.ICANON # ICANON must be set to recognize EOF
|
|
691 try: # use try/finally to ensure state gets restored
|
|
692 termios.tcsetattr(fd, termios.TCSADRAIN, new)
|
|
693 if 'CEOF' in dir(termios):
|
|
694 os.write (self.child_fd, '%c' % termios.CEOF)
|
|
695 else:
|
|
696 os.write (self.child_fd, '%c' % 4) # Silly platform does not define CEOF so assume CTRL-D
|
|
697 finally: # restore state
|
|
698 termios.tcsetattr(fd, termios.TCSADRAIN, old)
|
|
699
|
|
700 def eof (self):
|
|
701 """This returns 1 if the EOF exception was raised at some point.
|
|
702 """
|
|
703 return self.flag_eof
|
|
704
|
|
705 def terminate(self, force=0):
|
|
706 """This forces a child process to terminate.
|
|
707 It starts nicely with SIGHUP and SIGINT. If "force" is 1 then
|
|
708 moves onto SIGKILL.
|
|
709 This returns true if the child was terminated.
|
|
710 This returns false if the child could not be terminated.
|
|
711 """
|
|
712 if not self.isalive():
|
|
713 return 1
|
|
714 self.kill(signal.SIGHUP)
|
|
715 time.sleep(0.1)
|
|
716 if not self.isalive():
|
|
717 return 1
|
|
718 self.kill(signal.SIGCONT)
|
|
719 time.sleep(0.1)
|
|
720 if not self.isalive():
|
|
721 return 1
|
|
722 self.kill(signal.SIGINT)
|
|
723 time.sleep(0.1)
|
|
724 if not self.isalive():
|
|
725 return 1
|
|
726 if force:
|
|
727 self.kill(signal.SIGKILL)
|
|
728 time.sleep(0.1)
|
|
729 if not self.isalive():
|
|
730 return 1
|
|
731 else:
|
|
732 return 0
|
|
733 return 0
|
|
734 #raise ExceptionPexpect ('terminate() could not terminate child process. Try terminate(force=1)?')
|
|
735
|
|
736 def isalive(self):
|
|
737 """This tests if the child process is running or not.
|
|
738 This is non-blocking. If the child was terminated then this
|
|
739 will read the exitstatus or signalstatus of the child.
|
|
740 This returns 1 if the child process appears to be running or 0 if not.
|
|
741 It can take literally SECONDS for Solaris to return the right status.
|
|
742 """
|
|
743 if self.terminated:
|
|
744 return 0
|
|
745
|
|
746 if self.flag_eof:
|
|
747 # This is for Linux, which requires the blocking form of waitpid to get
|
|
748 # status of a defunct process. This is super-lame. The flag_eof would have
|
|
749 # been set in read_nonblocking(), so this should be safe.
|
|
750 waitpid_options = 0
|
|
751 else:
|
|
752 waitpid_options = os.WNOHANG
|
|
753
|
|
754 try:
|
|
755 pid, status = os.waitpid(self.pid, waitpid_options)
|
|
756 except OSError, e: # No child processes
|
|
757 if e[0] == errno.ECHILD:
|
|
758 raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?')
|
|
759 else:
|
|
760 raise e
|
|
761
|
|
762 # I have to do this twice for Solaris. I can't even believe that I figured this out...
|
|
763 # If waitpid() returns 0 it means that no child process wishes to
|
|
764 # report, and the value of status is undefined.
|
|
765 if pid == 0:
|
|
766 try:
|
|
767 pid, status = os.waitpid(self.pid, waitpid_options) ### os.WNOHANG) # Solaris!
|
|
768 except OSError, e: # This should never happen...
|
|
769 if e[0] == errno.ECHILD:
|
|
770 raise ExceptionPexpect ('isalive() encountered condition that should never happen. There was no child process. Did someone else call waitpid() on our process?')
|
|
771 else:
|
|
772 raise e
|
|
773
|
|
774 # If pid is still 0 after two calls to waitpid() then
|
|
775 # the process really is alive. This seems to work on all platforms, except
|
|
776 # for Irix which seems to require a blocking call on waitpid or select, so I let read_nonblocking
|
|
777 # take care of this situation (unfortunately, this requires waiting through the timeout).
|
|
778 if pid == 0:
|
|
779 return 1
|
|
780
|
|
781 if pid == 0:
|
|
782 return 1
|
|
783
|
|
784 if os.WIFEXITED (status):
|
|
785 self.status = status
|
|
786 self.exitstatus = os.WEXITSTATUS(status)
|
|
787 self.signalstatus = None
|
|
788 self.terminated = 1
|
|
789 return 0
|
|
790 elif os.WIFSIGNALED (status):
|
|
791 self.status = status
|
|
792 self.exitstatus = None
|
|
793 self.signalstatus = os.WTERMSIG(status)
|
|
794 self.terminated = 1
|
|
795 return 0
|
|
796 elif os.WIFSTOPPED (status):
|
|
797 raise ExceptionPexpect ('isalive() encountered condition where child process is stopped. This is not supported. Is some other process attempting job control with our child pid?')
|
|
798
|
|
799 raise ExceptionPexpect ('isalive() reached unexpected condition where waitpid matched child pid, but status was not matched by WIFEXITED, WIFSIGNALED, or WIFSTOPPED.')
|
|
800
|
|
801
|
|
802 def kill(self, sig):
|
|
803 """This sends the given signal to the child application.
|
|
804 In keeping with UNIX tradition it has a misleading name.
|
|
805 It does not necessarily kill the child unless
|
|
806 you send the right signal.
|
|
807 """
|
|
808 # Same as os.kill, but the pid is given for you.
|
|
809 if self.isalive():
|
|
810 os.kill(self.pid, sig)
|
|
811
|
|
812 def compile_pattern_list(self, patterns):
|
|
813 """This compiles a pattern-string or a list of pattern-strings.
|
|
814 Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or
|
|
815 a list of those. Patterns may also be None which results in
|
|
816 an empty list.
|
|
817
|
|
818 This is used by expect() when calling expect_list().
|
|
819 Thus expect() is nothing more than::
|
|
820 cpl = self.compile_pattern_list(pl)
|
|
821 return self.expect_list(clp, timeout)
|
|
822
|
|
823 If you are using expect() within a loop it may be more
|
|
824 efficient to compile the patterns first and then call expect_list().
|
|
825 This avoid calls in a loop to compile_pattern_list():
|
|
826 cpl = self.compile_pattern_list(my_pattern)
|
|
827 while some_condition:
|
|
828 ...
|
|
829 i = self.expect_list(clp, timeout)
|
|
830 ...
|
|
831 """
|
|
832 if patterns is None:
|
|
833 return []
|
|
834 if type(patterns) is not types.ListType:
|
|
835 patterns = [patterns]
|
|
836
|
|
837 compiled_pattern_list = []
|
|
838 for p in patterns:
|
|
839 if type(p) is types.StringType:
|
|
840 compiled_pattern_list.append(re.compile(p, re.DOTALL))
|
|
841 elif p is EOF:
|
|
842 compiled_pattern_list.append(EOF)
|
|
843 elif p is TIMEOUT:
|
|
844 compiled_pattern_list.append(TIMEOUT)
|
|
845 elif type(p) is type(re.compile('')):
|
|
846 compiled_pattern_list.append(p)
|
|
847 else:
|
|
848 raise TypeError ('Argument must be one of StringType, EOF, TIMEOUT, SRE_Pattern, or a list of those type. %s' % str(type(p)))
|
|
849
|
|
850 return compiled_pattern_list
|
|
851
|
|
852 def expect(self, pattern, timeout = -1, searchwindowsize=None):
|
|
853 """This seeks through the stream until a pattern is matched.
|
|
854 The pattern is overloaded and may take several types including a list.
|
|
855 The pattern can be a StringType, EOF, a compiled re, or
|
|
856 a list of those types. Strings will be compiled to re types.
|
|
857 This returns the index into the pattern list. If the pattern was
|
|
858 not a list this returns index 0 on a successful match.
|
|
859 This may raise exceptions for EOF or TIMEOUT.
|
|
860 To avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to
|
|
861 the pattern list.
|
|
862
|
|
863 After a match is found the instance attributes
|
|
864 'before', 'after' and 'match' will be set.
|
|
865 You can see all the data read before the match in 'before'.
|
|
866 You can see the data that was matched in 'after'.
|
|
867 The re.MatchObject used in the re match will be in 'match'.
|
|
868 If an error occured then 'before' will be set to all the
|
|
869 data read so far and 'after' and 'match' will be None.
|
|
870
|
|
871 If timeout is -1 then timeout will be set to the self.timeout value.
|
|
872
|
|
873 Note: A list entry may be EOF or TIMEOUT instead of a string.
|
|
874 This will catch these exceptions and return the index
|
|
875 of the list entry instead of raising the exception.
|
|
876 The attribute 'after' will be set to the exception type.
|
|
877 The attribute 'match' will be None.
|
|
878 This allows you to write code like this:
|
|
879 index = p.expect (['good', 'bad', pexpect.EOF, pexpect.TIMEOUT])
|
|
880 if index == 0:
|
|
881 do_something()
|
|
882 elif index == 1:
|
|
883 do_something_else()
|
|
884 elif index == 2:
|
|
885 do_some_other_thing()
|
|
886 elif index == 3:
|
|
887 do_something_completely_different()
|
|
888 instead of code like this:
|
|
889 try:
|
|
890 index = p.expect (['good', 'bad'])
|
|
891 if index == 0:
|
|
892 do_something()
|
|
893 elif index == 1:
|
|
894 do_something_else()
|
|
895 except EOF:
|
|
896 do_some_other_thing()
|
|
897 except TIMEOUT:
|
|
898 do_something_completely_different()
|
|
899 These two forms are equivalent. It all depends on what you want.
|
|
900 You can also just expect the EOF if you are waiting for all output
|
|
901 of a child to finish. For example:
|
|
902 p = pexpect.spawn('/bin/ls')
|
|
903 p.expect (pexpect.EOF)
|
|
904 print p.before
|
|
905
|
|
906 If you are trying to optimize for speed then see expect_list().
|
|
907 """
|
|
908 compiled_pattern_list = self.compile_pattern_list(pattern)
|
|
909 return self.expect_list(compiled_pattern_list, timeout, searchwindowsize)
|
|
910
|
|
911 def expect_list(self, pattern_list, timeout = -1, searchwindowsize = -1):
|
|
912 """This takes a list of compiled regular expressions and returns
|
|
913 the index into the pattern_list that matched the child's output.
|
|
914 The list may also contain EOF or TIMEOUT (which are not
|
|
915 compiled regular expressions). This method is similar to
|
|
916 the expect() method except that expect_list() does not
|
|
917 recompile the pattern list on every call.
|
|
918 This may help if you are trying to optimize for speed, otherwise
|
|
919 just use the expect() method. This is called by expect().
|
|
920 If timeout==-1 then the self.timeout value is used.
|
|
921 If searchwindowsize==-1 then the self.searchwindowsize value is used.
|
|
922 """
|
|
923 self.patterns = pattern_list
|
|
924
|
|
925 if timeout == -1:
|
|
926 timeout = self.timeout
|
|
927 if timeout != None:
|
|
928 end_time = time.time() + timeout
|
|
929 if searchwindowsize == -1:
|
|
930 searchwindowsize = self.searchwindowsize
|
|
931
|
|
932 try:
|
|
933 incoming = self.buffer
|
|
934 while 1: # Keep reading until exception or return.
|
|
935 # Sequence through the list of patterns looking for a match.
|
|
936 first_match = -1
|
|
937 for cre in pattern_list:
|
|
938 if cre is EOF or cre is TIMEOUT:
|
|
939 continue # The patterns for PexpectExceptions are handled differently.
|
|
940 if searchwindowsize is None: # search everything
|
|
941 match = cre.search(incoming)
|
|
942 else:
|
|
943 startpos = max(0, len(incoming) - searchwindowsize)
|
|
944 match = cre.search(incoming, startpos)
|
|
945 if match is None:
|
|
946 continue
|
|
947 if first_match > match.start() or first_match == -1:
|
|
948 first_match = match.start()
|
|
949 self.match = match
|
|
950 self.match_index = pattern_list.index(cre)
|
|
951 if first_match > -1:
|
|
952 self.buffer = incoming[self.match.end() : ]
|
|
953 self.before = incoming[ : self.match.start()]
|
|
954 self.after = incoming[self.match.start() : self.match.end()]
|
|
955 return self.match_index
|
|
956 # No match at this point
|
|
957 if timeout < 0 and timeout is not None:
|
|
958 raise TIMEOUT ('Timeout exceeded in expect_list().')
|
|
959 # Still have time left, so read more data
|
|
960 c = self.read_nonblocking (self.maxread, timeout)
|
|
961 incoming = incoming + c
|
|
962 if timeout is not None:
|
|
963 timeout = end_time - time.time()
|
|
964 except EOF, e:
|
|
965 self.buffer = ''
|
|
966 self.before = incoming
|
|
967 self.after = EOF
|
|
968 if EOF in pattern_list:
|
|
969 self.match = EOF
|
|
970 self.match_index = pattern_list.index(EOF)
|
|
971 return self.match_index
|
|
972 else:
|
|
973 self.match = None
|
|
974 self.match_index = None
|
|
975 raise EOF (str(e) + '\n' + str(self))
|
|
976 except TIMEOUT, e:
|
|
977 self.before = incoming
|
|
978 self.after = TIMEOUT
|
|
979 if TIMEOUT in pattern_list:
|
|
980 self.match = TIMEOUT
|
|
981 self.match_index = pattern_list.index(TIMEOUT)
|
|
982 return self.match_index
|
|
983 else:
|
|
984 self.match = None
|
|
985 self.match_index = None
|
|
986 raise TIMEOUT (str(e) + '\n' + str(self))
|
|
987 except Exception:
|
|
988 self.before = incoming
|
|
989 self.after = None
|
|
990 self.match = None
|
|
991 self.match_index = None
|
|
992 raise
|
|
993
|
|
994 def getwinsize(self):
|
|
995 """This returns the window size of the child tty.
|
|
996 The return value is a tuple of (rows, cols).
|
|
997 """
|
|
998 if 'TIOCGWINSZ' in dir(termios):
|
|
999 TIOCGWINSZ = termios.TIOCGWINSZ
|
|
1000 else:
|
|
1001 TIOCGWINSZ = 1074295912L # Assume
|
|
1002 s = struct.pack('HHHH', 0, 0, 0, 0)
|
|
1003 x = fcntl.ioctl(self.fileno(), TIOCGWINSZ, s)
|
|
1004 return struct.unpack('HHHH', x)[0:2]
|
|
1005
|
|
1006 def setwinsize(self, r, c):
|
|
1007 """This sets the window size of the child tty.
|
|
1008 This will cause a SIGWINCH signal to be sent to the child.
|
|
1009 This does not change the physical window size.
|
|
1010 It changes the size reported to TTY-aware applications like
|
|
1011 vi or curses -- applications that respond to the SIGWINCH signal.
|
|
1012 """
|
|
1013 # Check for buggy platforms. Some Python versions on some platforms
|
|
1014 # (notably OSF1 Alpha and RedHat 7.1) truncate the value for
|
|
1015 # termios.TIOCSWINSZ. It is not clear why this happens.
|
|
1016 # These platforms don't seem to handle the signed int very well;
|
|
1017 # yet other platforms like OpenBSD have a large negative value for
|
|
1018 # TIOCSWINSZ and they don't have a truncate problem.
|
|
1019 # Newer versions of Linux have totally different values for TIOCSWINSZ.
|
|
1020 # Note that this fix is a hack.
|
|
1021 if 'TIOCSWINSZ' in dir(termios):
|
|
1022 TIOCSWINSZ = termios.TIOCSWINSZ
|
|
1023 else:
|
|
1024 TIOCSWINSZ = -2146929561
|
|
1025 if TIOCSWINSZ == 2148037735L: # L is not required in Python >= 2.2.
|
|
1026 TIOCSWINSZ = -2146929561 # Same bits, but with sign.
|
|
1027 # Note, assume ws_xpixel and ws_ypixel are zero.
|
|
1028 s = struct.pack('HHHH', r, c, 0, 0)
|
|
1029 fcntl.ioctl(self.fileno(), TIOCSWINSZ, s)
|
|
1030
|
|
1031 def interact(self, escape_character = chr(29)):
|
|
1032 """This gives control of the child process to the interactive user
|
|
1033 (the human at the keyboard).
|
|
1034 Keystrokes are sent to the child process, and the stdout and stderr
|
|
1035 output of the child process is printed.
|
|
1036 When the user types the escape_character this method will stop.
|
|
1037 The default for escape_character is ^] (ASCII 29).
|
|
1038 This simply echos the child stdout and child stderr to the real
|
|
1039 stdout and it echos the real stdin to the child stdin.
|
|
1040
|
|
1041 Note that if you change the window size of the parent
|
|
1042 the SIGWINCH signal will not be passed through to the child.
|
|
1043 If you want the child window size to change when the parent's
|
|
1044 window size changes then do something like the following example:
|
|
1045 import pexpect, struct, fcntl, termios, signal, sys
|
|
1046 def sigwinch_passthrough (sig, data):
|
|
1047 s = struct.pack("HHHH", 0, 0, 0, 0)
|
|
1048 a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ , s))
|
|
1049 global p
|
|
1050 p.setwinsize(a[0],a[1])
|
|
1051 p = pexpect.spawn('/bin/bash') # Note this is global
|
|
1052 signal.signal(signal.SIGWINCH, sigwinch_passthrough)
|
|
1053 p.interact()
|
|
1054 """
|
|
1055 # Flush the buffer.
|
|
1056 self.stdout.write (self.buffer)
|
|
1057 self.stdout.flush()
|
|
1058 self.buffer = ''
|
|
1059 mode = tty.tcgetattr(self.STDIN_FILENO)
|
|
1060 tty.setraw(self.STDIN_FILENO)
|
|
1061 try:
|
|
1062 self.__interact_copy(escape_character)
|
|
1063 finally:
|
|
1064 tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode)
|
|
1065
|
|
1066 def __interact_writen(self, fd, data):
|
|
1067 """This is used by the interact() method.
|
|
1068 """
|
|
1069 while data != '' and self.isalive():
|
|
1070 n = os.write(fd, data)
|
|
1071 data = data[n:]
|
|
1072 def __interact_read(self, fd):
|
|
1073 """This is used by the interact() method.
|
|
1074 """
|
|
1075 return os.read(fd, 1000)
|
|
1076 def __interact_copy(self, escape_character = None):
|
|
1077 """This is used by the interact() method.
|
|
1078 """
|
|
1079 while self.isalive():
|
|
1080 try:
|
|
1081 r, w, e = select.select([self.child_fd, self.STDIN_FILENO], [], [])
|
|
1082 except select.errno, e:
|
|
1083 if e[0] != errno.EINTR:
|
|
1084 raise
|
|
1085 if self.child_fd in r:
|
|
1086 data = self.__interact_read(self.child_fd)
|
|
1087 if self.logfile != None:
|
|
1088 self.logfile.write (data)
|
|
1089 self.logfile.flush()
|
|
1090 os.write(self.STDOUT_FILENO, data)
|
|
1091 if self.STDIN_FILENO in r:
|
|
1092 data = self.__interact_read(self.STDIN_FILENO)
|
|
1093 self.__interact_writen(self.child_fd, data)
|
|
1094 if escape_character in data:
|
|
1095 break
|
|
1096 ##############################################################################
|
|
1097 # The following methods are no longer supported or allowed..
|
|
1098 def setmaxread (self, maxread):
|
|
1099 """This method is no longer supported or allowed.
|
|
1100 I don't like getters and setters without a good reason.
|
|
1101 """
|
|
1102 raise ExceptionPexpect ('This method is no longer supported or allowed. Just assign a value to the maxread member variable.')
|
|
1103 def expect_exact (self, pattern_list, timeout = -1):
|
|
1104 """This method is no longer supported or allowed.
|
|
1105 It was too hard to maintain and keep it up to date with expect_list.
|
|
1106 Few people used this method. Most people favored reliability over speed.
|
|
1107 The implementation is left in comments in case anyone needs to hack this
|
|
1108 feature back into their copy.
|
|
1109 If someone wants to diff this with expect_list and make them work
|
|
1110 nearly the same then I will consider adding this make in.
|
|
1111 """
|
|
1112 raise ExceptionPexpect ('This method is no longer supported or allowed.')
|
|
1113 def setlog (self, fileobject):
|
|
1114 """This method is no longer supported or allowed.
|
|
1115 """
|
|
1116 raise ExceptionPexpect ('This method is no longer supported or allowed. Just assign a value to the logfile member variable.')
|
|
1117
|
|
1118 ##############################################################################
|
|
1119 # End of spawn class
|
|
1120 ##############################################################################
|
|
1121
|
|
1122 def which (filename):
|
|
1123 """This takes a given filename; tries to find it in the environment path;
|
|
1124 then checks if it is executable.
|
|
1125 This returns the full path to the filename if found and executable.
|
|
1126 Otherwise this returns None.
|
|
1127 """
|
|
1128 # Special case where filename already contains a path.
|
|
1129 if os.path.dirname(filename) != '':
|
|
1130 if os.access (filename, os.X_OK):
|
|
1131 return filename
|
|
1132
|
|
1133 if not os.environ.has_key('PATH') or os.environ['PATH'] == '':
|
|
1134 p = os.defpath
|
|
1135 else:
|
|
1136 p = os.environ['PATH']
|
|
1137
|
|
1138 # Oddly enough this was the one line that made Pexpect
|
|
1139 # incompatible with Python 1.5.2.
|
|
1140 #pathlist = p.split (os.pathsep)
|
|
1141 pathlist = string.split (p, os.pathsep)
|
|
1142
|
|
1143 for path in pathlist:
|
|
1144 f = os.path.join(path, filename)
|
|
1145 if os.access(f, os.X_OK):
|
|
1146 return f
|
|
1147 return None
|
|
1148
|
|
1149 def split_command_line(command_line):
|
|
1150 """This splits a command line into a list of arguments.
|
|
1151 It splits arguments on spaces, but handles
|
|
1152 embedded quotes, doublequotes, and escaped characters.
|
|
1153 It's impossible to do this with a regular expression, so
|
|
1154 I wrote a little state machine to parse the command line.
|
|
1155 """
|
|
1156 arg_list = []
|
|
1157 arg = ''
|
|
1158
|
|
1159 # Constants to name the states we can be in.
|
|
1160 state_basic = 0
|
|
1161 state_esc = 1
|
|
1162 state_singlequote = 2
|
|
1163 state_doublequote = 3
|
|
1164 state_whitespace = 4 # The state of consuming whitespace between commands.
|
|
1165 state = state_basic
|
|
1166
|
|
1167 for c in command_line:
|
|
1168 if state == state_basic or state == state_whitespace:
|
|
1169 if c == '\\': # Escape the next character
|
|
1170 state = state_esc
|
|
1171 elif c == r"'": # Handle single quote
|
|
1172 state = state_singlequote
|
|
1173 elif c == r'"': # Handle double quote
|
|
1174 state = state_doublequote
|
|
1175 elif c.isspace():
|
|
1176 # Add arg to arg_list if we aren't in the middle of whitespace.
|
|
1177 if state == state_whitespace:
|
|
1178 None # Do nothing.
|
|
1179 else:
|
|
1180 arg_list.append(arg)
|
|
1181 arg = ''
|
|
1182 state = state_whitespace
|
|
1183 else:
|
|
1184 arg = arg + c
|
|
1185 state = state_basic
|
|
1186 elif state == state_esc:
|
|
1187 arg = arg + c
|
|
1188 state = state_basic
|
|
1189 elif state == state_singlequote:
|
|
1190 if c == r"'":
|
|
1191 state = state_basic
|
|
1192 else:
|
|
1193 arg = arg + c
|
|
1194 elif state == state_doublequote:
|
|
1195 if c == r'"':
|
|
1196 state = state_basic
|
|
1197 else:
|
|
1198 arg = arg + c
|
|
1199
|
|
1200 if arg != '':
|
|
1201 arg_list.append(arg)
|
|
1202 return arg_list
|
|
1203
|