Show More
This diff has been collapsed as it changes many lines, (1416 lines changed) Show them Hide them | |||||
@@ -1,4 +1,4 b'' | |||||
1 |
|
|
1 | '''Pexpect is a Python module for spawning child applications and controlling | |
2 | them automatically. Pexpect can be used for automating interactive applications |
|
2 | them automatically. Pexpect can be used for automating interactive applications | |
3 | such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup |
|
3 | such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup | |
4 | scripts for duplicating software package installations on different servers. It |
|
4 | scripts for duplicating software package installations on different servers. It | |
@@ -25,9 +25,9 b" expecting responses (waiting for patterns in the child's output)." | |||||
25 |
|
25 | |||
26 | For example:: |
|
26 | For example:: | |
27 |
|
27 | |||
28 |
child = pexpect.spawn('scp foo |
|
28 | child = pexpect.spawn('scp foo user@example.com:.') | |
29 |
child.expect |
|
29 | child.expect('Password:') | |
30 |
child.sendline |
|
30 | child.sendline(mypassword) | |
31 |
|
31 | |||
32 | This works even for commands that ask for passwords or other input outside of |
|
32 | This works even for commands that ask for passwords or other input outside of | |
33 | the normal stdio streams. For example, ssh reads input directly from the TTY |
|
33 | the normal stdio streams. For example, ssh reads input directly from the TTY | |
@@ -39,34 +39,34 b' vander Molen, George Todd, Noel Taylor, Nicolas D. Cesar, Alexander Gattin,' | |||||
39 | Jacques-Etienne Baudoux, Geoffrey Marshall, Francisco Lourenco, Glen Mabey, |
|
39 | Jacques-Etienne Baudoux, Geoffrey Marshall, Francisco Lourenco, Glen Mabey, | |
40 | Karthik Gurusamy, Fernando Perez, Corey Minyard, Jon Cohen, Guillaume |
|
40 | Karthik Gurusamy, Fernando Perez, Corey Minyard, Jon Cohen, Guillaume | |
41 | Chazarain, Andrew Ryan, Nick Craig-Wood, Andrew Stone, Jorgen Grahn, John |
|
41 | Chazarain, Andrew Ryan, Nick Craig-Wood, Andrew Stone, Jorgen Grahn, John | |
42 |
Spiegel, Jan Grant, Shane Ker |
|
42 | Spiegel, Jan Grant, and Shane Kerr. Let me know if I forgot anyone. | |
43 |
|
43 | |||
44 | Pexpect is free, open source, and all that good stuff. |
|
44 | Pexpect is free, open source, and all that good stuff. | |
45 |
|
||||
46 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
|
|||
47 | this software and associated documentation files (the "Software"), to deal in |
|
|||
48 | the Software without restriction, including without limitation the rights to |
|
|||
49 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
|
|||
50 | of the Software, and to permit persons to whom the Software is furnished to do |
|
|||
51 | so, subject to the following conditions: |
|
|||
52 |
|
||||
53 | The above copyright notice and this permission notice shall be included in all |
|
|||
54 | copies or substantial portions of the Software. |
|
|||
55 |
|
||||
56 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
|||
57 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
|||
58 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
|||
59 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
|||
60 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
|||
61 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
|||
62 | SOFTWARE. |
|
|||
63 |
|
||||
64 | Pexpect Copyright (c) 2008-2011 Noah Spurrier |
|
|||
65 | http://pexpect.sourceforge.net/ |
|
45 | http://pexpect.sourceforge.net/ | |
66 | """ |
|
46 | ||
|
47 | PEXPECT LICENSE | |||
|
48 | ||||
|
49 | This license is approved by the OSI and FSF as GPL-compatible. | |||
|
50 | http://opensource.org/licenses/isc-license.txt | |||
|
51 | ||||
|
52 | Copyright (c) 2012, Noah Spurrier <noah@noah.org> | |||
|
53 | PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY | |||
|
54 | PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE | |||
|
55 | COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. | |||
|
56 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||
|
57 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||
|
58 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||
|
59 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
|
60 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||
|
61 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||
|
62 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
|
63 | ||||
|
64 | ''' | |||
67 |
|
65 | |||
68 | try: |
|
66 | try: | |
69 |
import os |
|
67 | import os | |
|
68 | import sys | |||
|
69 | import time | |||
70 | import select |
|
70 | import select | |
71 | import re |
|
71 | import re | |
72 | import struct |
|
72 | import struct | |
@@ -79,97 +79,72 b' try:' | |||||
79 | import errno |
|
79 | import errno | |
80 | import traceback |
|
80 | import traceback | |
81 | import signal |
|
81 | import signal | |
82 | except ImportError as e: |
|
82 | import codecs | |
83 | raise ImportError (str(e) + """ |
|
83 | except ImportError: # pragma: no cover | |
|
84 | err = sys.exc_info()[1] | |||
|
85 | raise ImportError(str(err) + ''' | |||
84 |
|
86 | |||
85 | A critical module was not found. Probably this operating system does not |
|
87 | A critical module was not found. Probably this operating system does not | |
86 |
support it. Pexpect is intended for UNIX-like operating systems. |
|
88 | support it. Pexpect is intended for UNIX-like operating systems.''') | |
|
89 | ||||
|
90 | __version__ = '3.2' | |||
|
91 | __revision__ = '' | |||
|
92 | __all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'spawnu', 'run', 'runu', | |||
|
93 | 'which', 'split_command_line', '__version__', '__revision__'] | |||
87 |
|
94 | |||
88 | __version__ = '2.6.dev' |
|
95 | PY3 = (sys.version_info[0] >= 3) | |
89 | version = __version__ |
|
|||
90 | version_info = (2,6,'dev') |
|
|||
91 | __all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'spawnb', 'run', 'which', |
|
|||
92 | 'split_command_line', '__version__'] |
|
|||
93 |
|
96 | |||
94 | # Exception classes used by this module. |
|
97 | # Exception classes used by this module. | |
95 | class ExceptionPexpect(Exception): |
|
98 | class ExceptionPexpect(Exception): | |
96 |
|
99 | '''Base class for all exceptions raised by this module. | ||
97 | """Base class for all exceptions raised by this module. |
|
100 | ''' | |
98 | """ |
|
|||
99 |
|
101 | |||
100 | def __init__(self, value): |
|
102 | def __init__(self, value): | |
101 |
|
103 | super(ExceptionPexpect, self).__init__(value) | ||
102 | self.value = value |
|
104 | self.value = value | |
103 |
|
105 | |||
104 | def __str__(self): |
|
106 | def __str__(self): | |
105 |
|
||||
106 | return str(self.value) |
|
107 | return str(self.value) | |
107 |
|
108 | |||
108 | def get_trace(self): |
|
109 | def get_trace(self): | |
109 |
|
110 | '''This returns an abbreviated stack trace with lines that only concern | ||
110 | """This returns an abbreviated stack trace with lines that only concern |
|
|||
111 | the caller. In other words, the stack trace inside the Pexpect module |
|
111 | the caller. In other words, the stack trace inside the Pexpect module | |
112 |
is not included. |
|
112 | is not included. ''' | |
113 |
|
113 | |||
114 | tblist = traceback.extract_tb(sys.exc_info()[2]) |
|
114 | tblist = traceback.extract_tb(sys.exc_info()[2]) | |
115 | #tblist = filter(self.__filter_not_pexpect, tblist) |
|
115 | tblist = [item for item in tblist if 'pexpect/__init__' not in item[0]] | |
116 | tblist = [item for item in tblist if self.__filter_not_pexpect(item)] |
|
|||
117 | tblist = traceback.format_list(tblist) |
|
116 | tblist = traceback.format_list(tblist) | |
118 | return ''.join(tblist) |
|
117 | return ''.join(tblist) | |
119 |
|
118 | |||
120 | def __filter_not_pexpect(self, trace_list_item): |
|
|||
121 |
|
||||
122 | """This returns True if list item 0 the string 'pexpect.py' in it. """ |
|
|||
123 |
|
||||
124 | if trace_list_item[0].find('pexpect.py') == -1: |
|
|||
125 | return True |
|
|||
126 | else: |
|
|||
127 | return False |
|
|||
128 |
|
119 | |||
129 | class EOF(ExceptionPexpect): |
|
120 | class EOF(ExceptionPexpect): | |
|
121 | '''Raised when EOF is read from a child. | |||
|
122 | This usually means the child has exited.''' | |||
130 |
|
123 | |||
131 | """Raised when EOF is read from a child. This usually means the child has exited.""" |
|
|||
132 |
|
124 | |||
133 | class TIMEOUT(ExceptionPexpect): |
|
125 | class TIMEOUT(ExceptionPexpect): | |
134 |
|
126 | '''Raised when a read time exceeds the timeout. ''' | ||
135 | """Raised when a read time exceeds the timeout. """ |
|
|||
136 |
|
127 | |||
137 | ##class TIMEOUT_PATTERN(TIMEOUT): |
|
128 | ##class TIMEOUT_PATTERN(TIMEOUT): | |
138 |
## |
|
129 | ## '''Raised when the pattern match time exceeds the timeout. | |
139 | ## This is different than a read TIMEOUT because the child process may |
|
130 | ## This is different than a read TIMEOUT because the child process may | |
140 | ## give output, thus never give a TIMEOUT, but the output |
|
131 | ## give output, thus never give a TIMEOUT, but the output | |
141 | ## may never match a pattern. |
|
132 | ## may never match a pattern. | |
142 |
## |
|
133 | ## ''' | |
143 | ##class MAXBUFFER(ExceptionPexpect): |
|
134 | ##class MAXBUFFER(ExceptionPexpect): | |
144 |
## |
|
135 | ## '''Raised when a buffer fills before matching an expected pattern.''' | |
145 |
|
||||
146 | PY3 = (sys.version_info[0] >= 3) |
|
|||
147 |
|
||||
148 | unicode_type = str if PY3 else unicode |
|
|||
149 | basestring_type = str if PY3 else basestring |
|
|||
150 |
|
||||
151 | def _cast_bytes(s, enc): |
|
|||
152 | if isinstance(s, unicode_type): |
|
|||
153 | return s.encode(enc) |
|
|||
154 | return s |
|
|||
155 |
|
||||
156 | def _cast_unicode(s, enc): |
|
|||
157 | if isinstance(s, bytes): |
|
|||
158 | return s.decode(enc) |
|
|||
159 | return s |
|
|||
160 |
|
136 | |||
161 | re_type = type(re.compile('')) |
|
|||
162 |
|
137 | |||
163 |
def run |
|
138 | def run(command, timeout=-1, withexitstatus=False, events=None, | |
164 |
logfile=None, cwd=None, env=None |
|
139 | extra_args=None, logfile=None, cwd=None, env=None): | |
165 |
|
140 | |||
166 | """ |
|
141 | ''' | |
167 | This function runs the given command; waits for it to finish; then |
|
142 | This function runs the given command; waits for it to finish; then | |
168 | returns all output as a string. STDERR is included in output. If the full |
|
143 | returns all output as a string. STDERR is included in output. If the full | |
169 | path to the command is not given then the path is searched. |
|
144 | path to the command is not given then the path is searched. | |
170 |
|
145 | |||
171 | Note that lines are terminated by CR/LF (\\r\\n) combination even on |
|
146 | Note that lines are terminated by CR/LF (\\r\\n) combination even on | |
172 |
UNIX-like systems because this is the standard for pseudo |
|
147 | UNIX-like systems because this is the standard for pseudottys. If you set | |
173 | 'withexitstatus' to true, then run will return a tuple of (command_output, |
|
148 | 'withexitstatus' to true, then run will return a tuple of (command_output, | |
174 | exitstatus). If 'withexitstatus' is false then this returns just |
|
149 | exitstatus). If 'withexitstatus' is false then this returns just | |
175 | command_output. |
|
150 | command_output. | |
@@ -178,40 +153,37 b' def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None' | |||||
178 | For example, the following code uses spawn:: |
|
153 | For example, the following code uses spawn:: | |
179 |
|
154 | |||
180 | from pexpect import * |
|
155 | from pexpect import * | |
181 |
child = spawn('scp foo |
|
156 | child = spawn('scp foo user@example.com:.') | |
182 |
child.expect |
|
157 | child.expect('(?i)password') | |
183 |
child.sendline |
|
158 | child.sendline(mypassword) | |
184 |
|
159 | |||
185 | The previous code can be replace with the following:: |
|
160 | The previous code can be replace with the following:: | |
186 |
|
161 | |||
187 | from pexpect import * |
|
162 | from pexpect import * | |
188 |
run |
|
163 | run('scp foo user@example.com:.', events={'(?i)password': mypassword}) | |
189 |
|
164 | |||
190 | Examples |
|
165 | **Examples** | |
191 | ======== |
|
|||
192 |
|
166 | |||
193 | Start the apache daemon on the local machine:: |
|
167 | Start the apache daemon on the local machine:: | |
194 |
|
168 | |||
195 | from pexpect import * |
|
169 | from pexpect import * | |
196 |
run |
|
170 | run("/usr/local/apache/bin/apachectl start") | |
197 |
|
171 | |||
198 | Check in a file using SVN:: |
|
172 | Check in a file using SVN:: | |
199 |
|
173 | |||
200 | from pexpect import * |
|
174 | from pexpect import * | |
201 |
run |
|
175 | run("svn ci -m 'automatic commit' my_file.py") | |
202 |
|
176 | |||
203 | Run a command and capture exit status:: |
|
177 | Run a command and capture exit status:: | |
204 |
|
178 | |||
205 | from pexpect import * |
|
179 | from pexpect import * | |
206 |
(command_output, exitstatus) = run |
|
180 | (command_output, exitstatus) = run('ls -l /bin', withexitstatus=1) | |
207 |
|
||||
208 | Tricky Examples |
|
|||
209 | =============== |
|
|||
210 |
|
181 | |||
211 | The following will run SSH and execute 'ls -l' on the remote machine. The |
|
182 | The following will run SSH and execute 'ls -l' on the remote machine. The | |
212 | password 'secret' will be sent if the '(?i)password' pattern is ever seen:: |
|
183 | password 'secret' will be sent if the '(?i)password' pattern is ever seen:: | |
213 |
|
184 | |||
214 |
run |
|
185 | run("ssh username@machine.example.com 'ls -l'", | |
|
186 | events={'(?i)password':'secret\\n'}) | |||
215 |
|
187 | |||
216 | This will start mencoder to rip a video from DVD. This will also display |
|
188 | This will start mencoder to rip a video from DVD. This will also display | |
217 | progress ticks every 5 seconds as it runs. For example:: |
|
189 | progress ticks every 5 seconds as it runs. For example:: | |
@@ -219,7 +191,8 b' def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None' | |||||
219 | from pexpect import * |
|
191 | from pexpect import * | |
220 | def print_ticks(d): |
|
192 | def print_ticks(d): | |
221 | print d['event_count'], |
|
193 | print d['event_count'], | |
222 |
run |
|
194 | run("mencoder dvd://1 -o video.avi -oac copy -ovc copy", | |
|
195 | events={TIMEOUT:print_ticks}, timeout=5) | |||
223 |
|
196 | |||
224 | The 'events' argument should be a dictionary of patterns and responses. |
|
197 | The 'events' argument should be a dictionary of patterns and responses. | |
225 | Whenever one of the patterns is seen in the command out run() will send the |
|
198 | Whenever one of the patterns is seen in the command out run() will send the | |
@@ -233,92 +206,126 b' def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None' | |||||
233 | the next event. A callback may also return a string which will be sent to |
|
206 | the next event. A callback may also return a string which will be sent to | |
234 | the child. 'extra_args' is not used by directly run(). It provides a way to |
|
207 | the child. 'extra_args' is not used by directly run(). It provides a way to | |
235 | pass data to a callback function through run() through the locals |
|
208 | pass data to a callback function through run() through the locals | |
236 |
dictionary passed to a callback. |
|
209 | dictionary passed to a callback. | |
|
210 | ''' | |||
|
211 | return _run(command, timeout=timeout, withexitstatus=withexitstatus, | |||
|
212 | events=events, extra_args=extra_args, logfile=logfile, cwd=cwd, | |||
|
213 | env=env, _spawn=spawn) | |||
|
214 | ||||
|
215 | def runu(command, timeout=-1, withexitstatus=False, events=None, | |||
|
216 | extra_args=None, logfile=None, cwd=None, env=None, **kwargs): | |||
|
217 | """This offers the same interface as :func:`run`, but using unicode. | |||
|
218 | ||||
|
219 | Like :class:`spawnu`, you can pass ``encoding`` and ``errors`` parameters, | |||
|
220 | which will be used for both input and output. | |||
|
221 | """ | |||
|
222 | return _run(command, timeout=timeout, withexitstatus=withexitstatus, | |||
|
223 | events=events, extra_args=extra_args, logfile=logfile, cwd=cwd, | |||
|
224 | env=env, _spawn=spawnu, **kwargs) | |||
237 |
|
225 | |||
|
226 | def _run(command, timeout, withexitstatus, events, extra_args, logfile, cwd, | |||
|
227 | env, _spawn, **kwargs): | |||
238 | if timeout == -1: |
|
228 | if timeout == -1: | |
239 | child = spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env, |
|
229 | child = _spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env, | |
240 |
|
|
230 | **kwargs) | |
241 | else: |
|
231 | else: | |
242 | child = spawn(command, timeout=timeout, maxread=2000, logfile=logfile, |
|
232 | child = _spawn(command, timeout=timeout, maxread=2000, logfile=logfile, | |
243 |
|
|
233 | cwd=cwd, env=env, **kwargs) | |
244 | if events is not None: |
|
234 | if events is not None: | |
245 | patterns = events.keys() |
|
235 | patterns = list(events.keys()) | |
246 | responses = events.values() |
|
236 | responses = list(events.values()) | |
247 | else: |
|
237 | else: | |
248 |
|
|
238 | # This assumes EOF or TIMEOUT will eventually cause run to terminate. | |
249 |
|
|
239 | patterns = None | |
|
240 | responses = None | |||
250 | child_result_list = [] |
|
241 | child_result_list = [] | |
251 | event_count = 0 |
|
242 | event_count = 0 | |
252 |
while |
|
243 | while True: | |
253 | try: |
|
244 | try: | |
254 |
index = child.expect |
|
245 | index = child.expect(patterns) | |
255 |
if isinstance(child.after, |
|
246 | if isinstance(child.after, child.allowed_string_types): | |
256 | child_result_list.append(child.before + child.after) |
|
247 | child_result_list.append(child.before + child.after) | |
257 | else: # child.after may have been a TIMEOUT or EOF, so don't cat those. |
|
248 | else: | |
|
249 | # child.after may have been a TIMEOUT or EOF, | |||
|
250 | # which we don't want appended to the list. | |||
258 | child_result_list.append(child.before) |
|
251 | child_result_list.append(child.before) | |
259 |
if isinstance(responses[index], |
|
252 | if isinstance(responses[index], child.allowed_string_types): | |
260 | child.send(responses[index]) |
|
253 | child.send(responses[index]) | |
261 |
elif |
|
254 | elif isinstance(responses[index], types.FunctionType): | |
262 | callback_result = responses[index](locals()) |
|
255 | callback_result = responses[index](locals()) | |
263 | sys.stdout.flush() |
|
256 | sys.stdout.flush() | |
264 |
if isinstance(callback_result, |
|
257 | if isinstance(callback_result, child.allowed_string_types): | |
265 | child.send(callback_result) |
|
258 | child.send(callback_result) | |
266 | elif callback_result: |
|
259 | elif callback_result: | |
267 | break |
|
260 | break | |
268 | else: |
|
261 | else: | |
269 |
raise TypeError |
|
262 | raise TypeError('The callback must be a string or function.') | |
270 | event_count = event_count + 1 |
|
263 | event_count = event_count + 1 | |
271 |
except TIMEOUT |
|
264 | except TIMEOUT: | |
272 | child_result_list.append(child.before) |
|
265 | child_result_list.append(child.before) | |
273 | break |
|
266 | break | |
274 |
except EOF |
|
267 | except EOF: | |
275 | child_result_list.append(child.before) |
|
268 | child_result_list.append(child.before) | |
276 | break |
|
269 | break | |
277 |
child_result = child. |
|
270 | child_result = child.string_type().join(child_result_list) | |
278 | if withexitstatus: |
|
271 | if withexitstatus: | |
279 | child.close() |
|
272 | child.close() | |
280 | return (child_result, child.exitstatus) |
|
273 | return (child_result, child.exitstatus) | |
281 | else: |
|
274 | else: | |
282 | return child_result |
|
275 | return child_result | |
283 |
|
276 | |||
284 |
class spawn |
|
277 | class spawn(object): | |
285 | """Use this class to start and control child applications with a pure-bytes |
|
278 | '''This is the main class interface for Pexpect. Use this class to start | |
286 | interface.""" |
|
279 | and control child applications. ''' | |
287 |
|
280 | string_type = bytes | ||
288 | _buffer_type = bytes |
|
281 | if PY3: | |
289 | def _cast_buffer_type(self, s): |
|
282 | allowed_string_types = (bytes, str) | |
290 | return _cast_bytes(s, self.encoding) |
|
283 | @staticmethod | |
291 | _empty_buffer = b'' |
|
284 | def _chr(c): | |
292 | _pty_newline = b'\r\n' |
|
285 | return bytes([c]) | |
293 |
|
286 | linesep = os.linesep.encode('ascii') | ||
294 | # Some code needs this to exist, but it's mainly for the spawn subclass. |
|
287 | ||
295 | encoding = 'utf-8' |
|
288 | @staticmethod | |
296 |
|
289 | def write_to_stdout(b): | ||
297 | def __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize=None, |
|
290 | try: | |
298 | logfile=None, cwd=None, env=None): |
|
291 | return sys.stdout.buffer.write(b) | |
299 |
|
292 | except AttributeError: | ||
300 | """This is the constructor. The command parameter may be a string that |
|
293 | # If stdout has been replaced, it may not have .buffer | |
|
294 | return sys.stdout.write(b.decode('ascii', 'replace')) | |||
|
295 | else: | |||
|
296 | allowed_string_types = (basestring,) # analysis:ignore | |||
|
297 | _chr = staticmethod(chr) | |||
|
298 | linesep = os.linesep | |||
|
299 | write_to_stdout = sys.stdout.write | |||
|
300 | ||||
|
301 | encoding = None | |||
|
302 | ||||
|
303 | def __init__(self, command, args=[], timeout=30, maxread=2000, | |||
|
304 | searchwindowsize=None, logfile=None, cwd=None, env=None, | |||
|
305 | ignore_sighup=True): | |||
|
306 | ||||
|
307 | '''This is the constructor. The command parameter may be a string that | |||
301 | includes a command and any arguments to the command. For example:: |
|
308 | includes a command and any arguments to the command. For example:: | |
302 |
|
309 | |||
303 |
child = pexpect.spawn |
|
310 | child = pexpect.spawn('/usr/bin/ftp') | |
304 |
child = pexpect.spawn |
|
311 | child = pexpect.spawn('/usr/bin/ssh user@example.com') | |
305 |
child = pexpect.spawn |
|
312 | child = pexpect.spawn('ls -latr /tmp') | |
306 |
|
313 | |||
307 | You may also construct it with a list of arguments like so:: |
|
314 | You may also construct it with a list of arguments like so:: | |
308 |
|
315 | |||
309 |
child = pexpect.spawn |
|
316 | child = pexpect.spawn('/usr/bin/ftp', []) | |
310 |
child = pexpect.spawn |
|
317 | child = pexpect.spawn('/usr/bin/ssh', ['user@example.com']) | |
311 |
child = pexpect.spawn |
|
318 | child = pexpect.spawn('ls', ['-latr', '/tmp']) | |
312 |
|
319 | |||
313 | After this the child application will be created and will be ready to |
|
320 | After this the child application will be created and will be ready to | |
314 | talk to. For normal use, see expect() and send() and sendline(). |
|
321 | talk to. For normal use, see expect() and send() and sendline(). | |
315 |
|
322 | |||
316 | Remember that Pexpect does NOT interpret shell meta characters such as |
|
323 | Remember that Pexpect does NOT interpret shell meta characters such as | |
317 |
redirect, pipe, or wild cards (>, |, or *). This is a |
|
324 | redirect, pipe, or wild cards (``>``, ``|``, or ``*``). This is a | |
318 |
If you want to run a command and pipe it through |
|
325 | common mistake. If you want to run a command and pipe it through | |
319 | you must also start a shell. For example:: |
|
326 | another command then you must also start a shell. For example:: | |
320 |
|
327 | |||
321 |
child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > log |
|
328 | child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > logs.txt"') | |
322 | child.expect(pexpect.EOF) |
|
329 | child.expect(pexpect.EOF) | |
323 |
|
330 | |||
324 | The second form of spawn (where you pass a list of arguments) is useful |
|
331 | The second form of spawn (where you pass a list of arguments) is useful | |
@@ -326,7 +333,7 b' class spawnb(object):' | |||||
326 | argument list. This can make syntax more clear. For example, the |
|
333 | argument list. This can make syntax more clear. For example, the | |
327 | following is equivalent to the previous example:: |
|
334 | following is equivalent to the previous example:: | |
328 |
|
335 | |||
329 |
shell_cmd = 'ls -l | grep LOG > log |
|
336 | shell_cmd = 'ls -l | grep LOG > logs.txt' | |
330 | child = pexpect.spawn('/bin/bash', ['-c', shell_cmd]) |
|
337 | child = pexpect.spawn('/bin/bash', ['-c', shell_cmd]) | |
331 | child.expect(pexpect.EOF) |
|
338 | child.expect(pexpect.EOF) | |
332 |
|
339 | |||
@@ -337,14 +344,14 b' class spawnb(object):' | |||||
337 | output are read back from the child. This feature is useful in |
|
344 | output are read back from the child. This feature is useful in | |
338 | conjunction with searchwindowsize. |
|
345 | conjunction with searchwindowsize. | |
339 |
|
346 | |||
340 |
The searchwindowsize attribute sets the how far back in the incom |
|
347 | The searchwindowsize attribute sets the how far back in the incoming | |
341 | seach buffer Pexpect will search for pattern matches. Every time |
|
348 | seach buffer Pexpect will search for pattern matches. Every time | |
342 | Pexpect reads some data from the child it will append the data to the |
|
349 | Pexpect reads some data from the child it will append the data to the | |
343 |
incom |
|
350 | incoming buffer. The default is to search from the beginning of the | |
344 |
i |
|
351 | incoming buffer each time new data is read from the child. But this is | |
345 | very inefficient if you are running a command that generates a large |
|
352 | very inefficient if you are running a command that generates a large | |
346 | amount of data where you want to match The searchwindowsize does not |
|
353 | amount of data where you want to match. The searchwindowsize does not | |
347 |
|
|
354 | affect the size of the incoming data buffer. You will still have | |
348 | access to the full buffer after expect() returns. |
|
355 | access to the full buffer after expect() returns. | |
349 |
|
356 | |||
350 | The logfile member turns on or off logging. All input and output will |
|
357 | The logfile member turns on or off logging. All input and output will | |
@@ -355,7 +362,7 b' class spawnb(object):' | |||||
355 | Example log input and output to a file:: |
|
362 | Example log input and output to a file:: | |
356 |
|
363 | |||
357 | child = pexpect.spawn('some_command') |
|
364 | child = pexpect.spawn('some_command') | |
358 |
fout = |
|
365 | fout = file('mylog.txt','w') | |
359 | child.logfile = fout |
|
366 | child.logfile = fout | |
360 |
|
367 | |||
361 | Example log to stdout:: |
|
368 | Example log to stdout:: | |
@@ -375,6 +382,11 b' class spawnb(object):' | |||||
375 |
|
382 | |||
376 | self.logfile_send = fout |
|
383 | self.logfile_send = fout | |
377 |
|
384 | |||
|
385 | If ``ignore_sighup`` is True, the child process will ignore SIGHUP | |||
|
386 | signals. For now, the default is True, to preserve the behaviour of | |||
|
387 | earlier versions of Pexpect, but you should pass this explicitly if you | |||
|
388 | want to rely on it. | |||
|
389 | ||||
378 | The delaybeforesend helps overcome a weird behavior that many users |
|
390 | The delaybeforesend helps overcome a weird behavior that many users | |
379 | were experiencing. The typical problem was that a user would expect() a |
|
391 | were experiencing. The typical problem was that a user would expect() a | |
380 | "Password:" prompt and then immediately call sendline() to send the |
|
392 | "Password:" prompt and then immediately call sendline() to send the | |
@@ -403,7 +415,7 b' class spawnb(object):' | |||||
403 | signalstatus will store the signal value and exitstatus will be None. |
|
415 | signalstatus will store the signal value and exitstatus will be None. | |
404 | If you need more detail you can also read the self.status member which |
|
416 | If you need more detail you can also read the self.status member which | |
405 | stores the status returned by os.waitpid. You can interpret this using |
|
417 | stores the status returned by os.waitpid. You can interpret this using | |
406 |
os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG. |
|
418 | os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG. ''' | |
407 |
|
419 | |||
408 | self.STDIN_FILENO = pty.STDIN_FILENO |
|
420 | self.STDIN_FILENO = pty.STDIN_FILENO | |
409 | self.STDOUT_FILENO = pty.STDOUT_FILENO |
|
421 | self.STDOUT_FILENO = pty.STDOUT_FILENO | |
@@ -421,76 +433,104 b' class spawnb(object):' | |||||
421 | self.terminated = True |
|
433 | self.terminated = True | |
422 | self.exitstatus = None |
|
434 | self.exitstatus = None | |
423 | self.signalstatus = None |
|
435 | self.signalstatus = None | |
424 |
|
|
436 | # status returned by os.waitpid | |
|
437 | self.status = None | |||
425 | self.flag_eof = False |
|
438 | self.flag_eof = False | |
426 | self.pid = None |
|
439 | self.pid = None | |
427 |
|
|
440 | # the chile filedescriptor is initially closed | |
|
441 | self.child_fd = -1 | |||
428 | self.timeout = timeout |
|
442 | self.timeout = timeout | |
429 | self.delimiter = EOF |
|
443 | self.delimiter = EOF | |
430 | self.logfile = logfile |
|
444 | self.logfile = logfile | |
431 |
|
|
445 | # input from child (read_nonblocking) | |
432 |
self.logfile_ |
|
446 | self.logfile_read = None | |
433 | self.maxread = maxread # max bytes to read at one time into buffer |
|
447 | # output to send (send, sendline) | |
434 | self.buffer = self._empty_buffer # This is the read buffer. See maxread. |
|
448 | self.logfile_send = None | |
435 | self.searchwindowsize = searchwindowsize # Anything before searchwindowsize point is preserved, but not searched. |
|
449 | # max bytes to read at one time into buffer | |
436 | # Most Linux machines don't like delaybeforesend to be below 0.03 (30 ms). |
|
450 | self.maxread = maxread | |
437 | self.delaybeforesend = 0.05 # Sets sleep time used just before sending data to child. Time in seconds. |
|
451 | # This is the read buffer. See maxread. | |
438 | self.delayafterclose = 0.1 # Sets delay in close() method to allow kernel time to update process status. Time in seconds. |
|
452 | self.buffer = self.string_type() | |
439 | self.delayafterterminate = 0.1 # Sets delay in terminate() method to allow kernel time to update process status. Time in seconds. |
|
453 | # Data before searchwindowsize point is preserved, but not searched. | |
440 | self.softspace = False # File-like object. |
|
454 | self.searchwindowsize = searchwindowsize | |
441 | self.name = '<' + repr(self) + '>' # File-like object. |
|
455 | # Delay used before sending data to child. Time in seconds. | |
442 | self.closed = True # File-like object. |
|
456 | # Most Linux machines don't like this to be below 0.03 (30 ms). | |
|
457 | self.delaybeforesend = 0.05 | |||
|
458 | # Used by close() to give kernel time to update process status. | |||
|
459 | # Time in seconds. | |||
|
460 | self.delayafterclose = 0.1 | |||
|
461 | # Used by terminate() to give kernel time to update process status. | |||
|
462 | # Time in seconds. | |||
|
463 | self.delayafterterminate = 0.1 | |||
|
464 | self.softspace = False | |||
|
465 | self.name = '<' + repr(self) + '>' | |||
|
466 | self.closed = True | |||
443 | self.cwd = cwd |
|
467 | self.cwd = cwd | |
444 | self.env = env |
|
468 | self.env = env | |
445 | self.__irix_hack = (sys.platform.lower().find('irix')>=0) # This flags if we are running on irix |
|
469 | self.ignore_sighup = ignore_sighup | |
|
470 | # This flags if we are running on irix | |||
|
471 | self.__irix_hack = (sys.platform.lower().find('irix') >= 0) | |||
446 | # Solaris uses internal __fork_pty(). All others use pty.fork(). |
|
472 | # Solaris uses internal __fork_pty(). All others use pty.fork(). | |
447 | if 'solaris' in sys.platform.lower() or 'sunos5' in sys.platform.lower(): |
|
473 | if ((sys.platform.lower().find('solaris') >= 0) | |
|
474 | or (sys.platform.lower().find('sunos5') >= 0)): | |||
448 | self.use_native_pty_fork = False |
|
475 | self.use_native_pty_fork = False | |
449 | else: |
|
476 | else: | |
450 | self.use_native_pty_fork = True |
|
477 | self.use_native_pty_fork = True | |
451 |
|
478 | |||
452 |
|
479 | # Support subclasses that do not use command or args. | ||
453 | # allow dummy instances for subclasses that may not use command or args. |
|
|||
454 | if command is None: |
|
480 | if command is None: | |
455 | self.command = None |
|
481 | self.command = None | |
456 | self.args = None |
|
482 | self.args = None | |
457 | self.name = '<pexpect factory incomplete>' |
|
483 | self.name = '<pexpect factory incomplete>' | |
458 | else: |
|
484 | else: | |
459 |
self._spawn |
|
485 | self._spawn(command, args) | |
460 |
|
486 | |||
461 | def __del__(self): |
|
487 | @staticmethod | |
|
488 | def _coerce_expect_string(s): | |||
|
489 | if not isinstance(s, bytes): | |||
|
490 | return s.encode('ascii') | |||
|
491 | return s | |||
|
492 | ||||
|
493 | @staticmethod | |||
|
494 | def _coerce_send_string(s): | |||
|
495 | if not isinstance(s, bytes): | |||
|
496 | return s.encode('utf-8') | |||
|
497 | return s | |||
462 |
|
498 | |||
463 | """This makes sure that no system resources are left open. Python only |
|
499 | @staticmethod | |
|
500 | def _coerce_read_string(s): | |||
|
501 | return s | |||
|
502 | ||||
|
503 | def __del__(self): | |||
|
504 | '''This makes sure that no system resources are left open. Python only | |||
464 | garbage collects Python objects. OS file descriptors are not Python |
|
505 | garbage collects Python objects. OS file descriptors are not Python | |
465 | objects, so they must be handled explicitly. If the child file |
|
506 | objects, so they must be handled explicitly. If the child file | |
466 | descriptor was opened outside of this class (passed to the constructor) |
|
507 | descriptor was opened outside of this class (passed to the constructor) | |
467 |
then this does not close it. |
|
508 | then this does not close it. ''' | |
468 |
|
509 | |||
469 | if not self.closed: |
|
510 | if not self.closed: | |
470 | # It is possible for __del__ methods to execute during the |
|
511 | # It is possible for __del__ methods to execute during the | |
471 | # teardown of the Python VM itself. Thus self.close() may |
|
512 | # teardown of the Python VM itself. Thus self.close() may | |
472 | # trigger an exception because os.close may be None. |
|
513 | # trigger an exception because os.close may be None. | |
473 | # -- Fernando Perez |
|
|||
474 | try: |
|
514 | try: | |
475 | self.close() |
|
515 | self.close() | |
|
516 | # which exception, shouldnt' we catch explicitly .. ? | |||
476 | except: |
|
517 | except: | |
477 | pass |
|
518 | pass | |
478 |
|
519 | |||
479 | def __str__(self): |
|
520 | def __str__(self): | |
480 |
|
521 | '''This returns a human-readable string that represents the state of | ||
481 | """This returns a human-readable string that represents the state of |
|
522 | the object. ''' | |
482 | the object. """ |
|
|||
483 |
|
523 | |||
484 | s = [] |
|
524 | s = [] | |
485 | s.append(repr(self)) |
|
525 | s.append(repr(self)) | |
486 | s.append('version: ' + __version__) |
|
526 | s.append('version: ' + __version__) | |
487 | s.append('command: ' + str(self.command)) |
|
527 | s.append('command: ' + str(self.command)) | |
488 |
s.append('args: ' |
|
528 | s.append('args: %r' % (self.args,)) | |
489 |
s.append('searcher: ' |
|
529 | s.append('searcher: %r' % (self.searcher,)) | |
490 |
s.append('buffer (last 100 chars): ' |
|
530 | s.append('buffer (last 100 chars): %r' % (self.buffer)[-100:],) | |
491 |
s.append('before (last 100 chars): ' |
|
531 | s.append('before (last 100 chars): %r' % (self.before)[-100:],) | |
492 |
s.append('after: ' |
|
532 | s.append('after: %r' % (self.after,)) | |
493 |
s.append('match: ' |
|
533 | s.append('match: %r' % (self.match,)) | |
494 | s.append('match_index: ' + str(self.match_index)) |
|
534 | s.append('match_index: ' + str(self.match_index)) | |
495 | s.append('exitstatus: ' + str(self.exitstatus)) |
|
535 | s.append('exitstatus: ' + str(self.exitstatus)) | |
496 | s.append('flag_eof: ' + str(self.flag_eof)) |
|
536 | s.append('flag_eof: ' + str(self.flag_eof)) | |
@@ -510,12 +550,11 b' class spawnb(object):' | |||||
510 | s.append('delayafterterminate: ' + str(self.delayafterterminate)) |
|
550 | s.append('delayafterterminate: ' + str(self.delayafterterminate)) | |
511 | return '\n'.join(s) |
|
551 | return '\n'.join(s) | |
512 |
|
552 | |||
513 | def _spawn(self,command,args=[]): |
|
553 | def _spawn(self, command, args=[]): | |
514 |
|
554 | '''This starts the given command in a child process. This does all the | ||
515 | """This starts the given command in a child process. This does all the |
|
|||
516 | fork/exec type of stuff for a pty. This is called by __init__. If args |
|
555 | fork/exec type of stuff for a pty. This is called by __init__. If args | |
517 | is empty then command will be parsed (split on spaces) and args will be |
|
556 | is empty then command will be parsed (split on spaces) and args will be | |
518 |
set to parsed arguments. |
|
557 | set to parsed arguments. ''' | |
519 |
|
558 | |||
520 | # The pid and child_fd of this object get set by this method. |
|
559 | # The pid and child_fd of this object get set by this method. | |
521 | # Note that it is difficult for this method to fail. |
|
560 | # Note that it is difficult for this method to fail. | |
@@ -523,47 +562,57 b' class spawnb(object):' | |||||
523 | # So the only way you can tell if the child process started |
|
562 | # So the only way you can tell if the child process started | |
524 | # or not is to try to read from the file descriptor. If you get |
|
563 | # or not is to try to read from the file descriptor. If you get | |
525 | # EOF immediately then it means that the child is already dead. |
|
564 | # EOF immediately then it means that the child is already dead. | |
526 |
# That may not necessarily be bad because you may have |
|
565 | # That may not necessarily be bad because you may have spawned a child | |
527 | # that performs some task; creates no stdout output; and then dies. |
|
566 | # that performs some task; creates no stdout output; and then dies. | |
528 |
|
567 | |||
529 | # If command is an int type then it may represent a file descriptor. |
|
568 | # If command is an int type then it may represent a file descriptor. | |
530 |
if |
|
569 | if isinstance(command, type(0)): | |
531 | raise ExceptionPexpect ('Command is an int type. If this is a file descriptor then maybe you want to use fdpexpect.fdspawn which takes an existing file descriptor instead of a command string.') |
|
570 | raise ExceptionPexpect('Command is an int type. ' + | |
|
571 | 'If this is a file descriptor then maybe you want to ' + | |||
|
572 | 'use fdpexpect.fdspawn which takes an existing ' + | |||
|
573 | 'file descriptor instead of a command string.') | |||
532 |
|
574 | |||
533 |
if t |
|
575 | if not isinstance(args, type([])): | |
534 |
raise TypeError |
|
576 | raise TypeError('The argument, args, must be a list.') | |
535 |
|
577 | |||
536 | if args == []: |
|
578 | if args == []: | |
537 | self.args = split_command_line(command) |
|
579 | self.args = split_command_line(command) | |
538 | self.command = self.args[0] |
|
580 | self.command = self.args[0] | |
539 | else: |
|
581 | else: | |
540 | self.args = args[:] # work with a copy |
|
582 | # Make a shallow copy of the args list. | |
541 |
self.args |
|
583 | self.args = args[:] | |
|
584 | self.args.insert(0, command) | |||
542 | self.command = command |
|
585 | self.command = command | |
543 |
|
586 | |||
544 | command_with_path = which(self.command) |
|
587 | command_with_path = which(self.command) | |
545 | if command_with_path is None: |
|
588 | if command_with_path is None: | |
546 |
raise ExceptionPexpect |
|
589 | raise ExceptionPexpect('The command was not found or was not ' + | |
|
590 | 'executable: %s.' % self.command) | |||
547 | self.command = command_with_path |
|
591 | self.command = command_with_path | |
548 | self.args[0] = self.command |
|
592 | self.args[0] = self.command | |
549 |
|
593 | |||
550 |
self.name = '<' + ' '.join |
|
594 | self.name = '<' + ' '.join(self.args) + '>' | |
551 |
|
595 | |||
552 |
assert self.pid is None, 'The pid member |
|
596 | assert self.pid is None, 'The pid member must be None.' | |
553 |
assert self.command is not None, 'The command member |
|
597 | assert self.command is not None, 'The command member must not be None.' | |
554 |
|
598 | |||
555 | if self.use_native_pty_fork: |
|
599 | if self.use_native_pty_fork: | |
556 | try: |
|
600 | try: | |
557 | self.pid, self.child_fd = pty.fork() |
|
601 | self.pid, self.child_fd = pty.fork() | |
558 |
except OSError |
|
602 | except OSError: | |
559 | raise ExceptionPexpect('Error! pty.fork() failed: ' + str(e)) |
|
603 | err = sys.exc_info()[1] | |
560 | else: # Use internal __fork_pty |
|
604 | raise ExceptionPexpect('pty.fork() failed: ' + str(err)) | |
|
605 | else: | |||
|
606 | # Use internal __fork_pty | |||
561 | self.pid, self.child_fd = self.__fork_pty() |
|
607 | self.pid, self.child_fd = self.__fork_pty() | |
562 |
|
608 | |||
563 |
if self.pid == 0: |
|
609 | if self.pid == 0: | |
|
610 | # Child | |||
564 | try: |
|
611 | try: | |
565 |
|
|
612 | # used by setwinsize() | |
|
613 | self.child_fd = sys.stdout.fileno() | |||
566 | self.setwinsize(24, 80) |
|
614 | self.setwinsize(24, 80) | |
|
615 | # which exception, shouldnt' we catch explicitly .. ? | |||
567 | except: |
|
616 | except: | |
568 | # Some platforms do not like setwinsize (Cygwin). |
|
617 | # Some platforms do not like setwinsize (Cygwin). | |
569 | # This will cause problem when running applications that |
|
618 | # This will cause problem when running applications that | |
@@ -572,16 +621,14 b' class spawnb(object):' | |||||
572 | pass |
|
621 | pass | |
573 | # Do not allow child to inherit open file descriptors from parent. |
|
622 | # Do not allow child to inherit open file descriptors from parent. | |
574 | max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0] |
|
623 | max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0] | |
575 |
for i in range |
|
624 | for i in range(3, max_fd): | |
576 | try: |
|
625 | try: | |
577 |
os.close |
|
626 | os.close(i) | |
578 | except OSError: |
|
627 | except OSError: | |
579 | pass |
|
628 | pass | |
580 |
|
629 | |||
581 | # I don't know why this works, but ignoring SIGHUP fixes a |
|
630 | if self.ignore_sighup: | |
582 | # problem when trying to start a Java daemon with sudo |
|
631 | signal.signal(signal.SIGHUP, signal.SIG_IGN) | |
583 | # (specifically, Tomcat). |
|
|||
584 | signal.signal(signal.SIGHUP, signal.SIG_IGN) |
|
|||
585 |
|
632 | |||
586 | if self.cwd is not None: |
|
633 | if self.cwd is not None: | |
587 | os.chdir(self.cwd) |
|
634 | os.chdir(self.cwd) | |
@@ -595,8 +642,7 b' class spawnb(object):' | |||||
595 | self.closed = False |
|
642 | self.closed = False | |
596 |
|
643 | |||
597 | def __fork_pty(self): |
|
644 | def __fork_pty(self): | |
598 |
|
645 | '''This implements a substitute for the forkpty system call. This | ||
599 | """This implements a substitute for the forkpty system call. This |
|
|||
600 | should be more portable than the pty.fork() function. Specifically, |
|
646 | should be more portable than the pty.fork() function. Specifically, | |
601 | this should work on Solaris. |
|
647 | this should work on Solaris. | |
602 |
|
648 | |||
@@ -607,15 +653,15 b' class spawnb(object):' | |||||
607 |
|
653 | |||
608 | http://mail.python.org/pipermail/python-dev/2003-May/035281.html |
|
654 | http://mail.python.org/pipermail/python-dev/2003-May/035281.html | |
609 |
|
655 | |||
610 |
|
|
656 | ''' | |
611 |
|
657 | |||
612 | parent_fd, child_fd = os.openpty() |
|
658 | parent_fd, child_fd = os.openpty() | |
613 | if parent_fd < 0 or child_fd < 0: |
|
659 | if parent_fd < 0 or child_fd < 0: | |
614 |
raise ExceptionPexpect(" |
|
660 | raise ExceptionPexpect("Could not open with os.openpty().") | |
615 |
|
661 | |||
616 | pid = os.fork() |
|
662 | pid = os.fork() | |
617 | if pid < 0: |
|
663 | if pid < 0: | |
618 |
raise ExceptionPexpect(" |
|
664 | raise ExceptionPexpect("Failed os.fork().") | |
619 | elif pid == 0: |
|
665 | elif pid == 0: | |
620 | # Child. |
|
666 | # Child. | |
621 | os.close(parent_fd) |
|
667 | os.close(parent_fd) | |
@@ -634,18 +680,18 b' class spawnb(object):' | |||||
634 | return pid, parent_fd |
|
680 | return pid, parent_fd | |
635 |
|
681 | |||
636 | def __pty_make_controlling_tty(self, tty_fd): |
|
682 | def __pty_make_controlling_tty(self, tty_fd): | |
637 |
|
683 | '''This makes the pseudo-terminal the controlling tty. This should be | ||
638 | """This makes the pseudo-terminal the controlling tty. This should be |
|
|||
639 | more portable than the pty.fork() function. Specifically, this should |
|
684 | more portable than the pty.fork() function. Specifically, this should | |
640 |
work on Solaris. |
|
685 | work on Solaris. ''' | |
641 |
|
686 | |||
642 | child_name = os.ttyname(tty_fd) |
|
687 | child_name = os.ttyname(tty_fd) | |
643 |
|
688 | |||
644 | # Disconnect from controlling tty. Harmless if not already connected. |
|
689 | # Disconnect from controlling tty. Harmless if not already connected. | |
645 | try: |
|
690 | try: | |
646 |
fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) |
|
691 | fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) | |
647 | if fd >= 0: |
|
692 | if fd >= 0: | |
648 | os.close(fd) |
|
693 | os.close(fd) | |
|
694 | # which exception, shouldnt' we catch explicitly .. ? | |||
649 | except: |
|
695 | except: | |
650 | # Already disconnected. This happens if running inside cron. |
|
696 | # Already disconnected. This happens if running inside cron. | |
651 | pass |
|
697 | pass | |
@@ -655,71 +701,68 b' class spawnb(object):' | |||||
655 | # Verify we are disconnected from controlling tty |
|
701 | # Verify we are disconnected from controlling tty | |
656 | # by attempting to open it again. |
|
702 | # by attempting to open it again. | |
657 | try: |
|
703 | try: | |
658 |
fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) |
|
704 | fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) | |
659 | if fd >= 0: |
|
705 | if fd >= 0: | |
660 | os.close(fd) |
|
706 | os.close(fd) | |
661 |
raise ExceptionPexpect( |
|
707 | raise ExceptionPexpect('Failed to disconnect from ' + | |
|
708 | 'controlling tty. It is still possible to open /dev/tty.') | |||
|
709 | # which exception, shouldnt' we catch explicitly .. ? | |||
662 | except: |
|
710 | except: | |
663 | # Good! We are disconnected from a controlling tty. |
|
711 | # Good! We are disconnected from a controlling tty. | |
664 | pass |
|
712 | pass | |
665 |
|
713 | |||
666 | # Verify we can open child pty. |
|
714 | # Verify we can open child pty. | |
667 |
fd = os.open(child_name, os.O_RDWR) |
|
715 | fd = os.open(child_name, os.O_RDWR) | |
668 | if fd < 0: |
|
716 | if fd < 0: | |
669 |
raise ExceptionPexpect(" |
|
717 | raise ExceptionPexpect("Could not open child pty, " + child_name) | |
670 | else: |
|
718 | else: | |
671 | os.close(fd) |
|
719 | os.close(fd) | |
672 |
|
720 | |||
673 | # Verify we now have a controlling tty. |
|
721 | # Verify we now have a controlling tty. | |
674 | fd = os.open("/dev/tty", os.O_WRONLY) |
|
722 | fd = os.open("/dev/tty", os.O_WRONLY) | |
675 | if fd < 0: |
|
723 | if fd < 0: | |
676 |
raise ExceptionPexpect(" |
|
724 | raise ExceptionPexpect("Could not open controlling tty, /dev/tty") | |
677 | else: |
|
725 | else: | |
678 | os.close(fd) |
|
726 | os.close(fd) | |
679 |
|
727 | |||
680 |
def fileno |
|
728 | def fileno(self): | |
681 |
|
729 | '''This returns the file descriptor of the pty for the child. | ||
682 | """This returns the file descriptor of the pty for the child. |
|
730 | ''' | |
683 | """ |
|
|||
684 |
|
||||
685 | return self.child_fd |
|
731 | return self.child_fd | |
686 |
|
732 | |||
687 |
def close |
|
733 | def close(self, force=True): | |
688 |
|
734 | '''This closes the connection with the child application. Note that | ||
689 | """This closes the connection with the child application. Note that |
|
|||
690 | calling close() more than once is valid. This emulates standard Python |
|
735 | calling close() more than once is valid. This emulates standard Python | |
691 | behavior with files. Set force to True if you want to make sure that |
|
736 | behavior with files. Set force to True if you want to make sure that | |
692 | the child is terminated (SIGKILL is sent if the child ignores SIGHUP |
|
737 | the child is terminated (SIGKILL is sent if the child ignores SIGHUP | |
693 |
and SIGINT). |
|
738 | and SIGINT). ''' | |
694 |
|
739 | |||
695 | if not self.closed: |
|
740 | if not self.closed: | |
696 | self.flush() |
|
741 | self.flush() | |
697 |
os.close |
|
742 | os.close(self.child_fd) | |
698 |
|
|
743 | # Give kernel time to update process status. | |
|
744 | time.sleep(self.delayafterclose) | |||
699 | if self.isalive(): |
|
745 | if self.isalive(): | |
700 | if not self.terminate(force): |
|
746 | if not self.terminate(force): | |
701 |
raise ExceptionPexpect |
|
747 | raise ExceptionPexpect('Could not terminate the child.') | |
702 | self.child_fd = -1 |
|
748 | self.child_fd = -1 | |
703 | self.closed = True |
|
749 | self.closed = True | |
704 | #self.pid = None |
|
750 | #self.pid = None | |
705 |
|
751 | |||
706 |
def flush |
|
752 | def flush(self): | |
707 |
|
753 | '''This does nothing. It is here to support the interface for a | ||
708 | """This does nothing. It is here to support the interface for a |
|
754 | File-like object. ''' | |
709 | File-like object. """ |
|
|||
710 |
|
755 | |||
711 | pass |
|
756 | pass | |
712 |
|
757 | |||
713 |
def isatty |
|
758 | def isatty(self): | |
714 |
|
759 | '''This returns True if the file descriptor is open and connected to a | ||
715 | """This returns True if the file descriptor is open and connected to a |
|
760 | tty(-like) device, else False. ''' | |
716 | tty(-like) device, else False. """ |
|
|||
717 |
|
761 | |||
718 | return os.isatty(self.child_fd) |
|
762 | return os.isatty(self.child_fd) | |
719 |
|
763 | |||
720 |
def waitnoecho |
|
764 | def waitnoecho(self, timeout=-1): | |
721 |
|
765 | '''This waits until the terminal ECHO flag is set False. This returns | ||
722 | """This waits until the terminal ECHO flag is set False. This returns |
|
|||
723 | True if the echo mode is off. This returns False if the ECHO flag was |
|
766 | True if the echo mode is off. This returns False if the ECHO flag was | |
724 | not set False before the timeout. This can be used to detect when the |
|
767 | not set False before the timeout. This can be used to detect when the | |
725 | child is waiting for a password. Usually a child application will turn |
|
768 | child is waiting for a password. Usually a child application will turn | |
@@ -727,13 +770,13 b' class spawnb(object):' | |||||
727 | example, instead of expecting the "password:" prompt you can wait for |
|
770 | example, instead of expecting the "password:" prompt you can wait for | |
728 | the child to set ECHO off:: |
|
771 | the child to set ECHO off:: | |
729 |
|
772 | |||
730 |
p = pexpect.spawn |
|
773 | p = pexpect.spawn('ssh user@example.com') | |
731 | p.waitnoecho() |
|
774 | p.waitnoecho() | |
732 | p.sendline(mypassword) |
|
775 | p.sendline(mypassword) | |
733 |
|
776 | |||
734 | If timeout==-1 then this method will use the value in self.timeout. |
|
777 | If timeout==-1 then this method will use the value in self.timeout. | |
735 | If timeout==None then this method to block until ECHO flag is False. |
|
778 | If timeout==None then this method to block until ECHO flag is False. | |
736 |
|
|
779 | ''' | |
737 |
|
780 | |||
738 | if timeout == -1: |
|
781 | if timeout == -1: | |
739 | timeout = self.timeout |
|
782 | timeout = self.timeout | |
@@ -748,47 +791,45 b' class spawnb(object):' | |||||
748 | timeout = end_time - time.time() |
|
791 | timeout = end_time - time.time() | |
749 | time.sleep(0.1) |
|
792 | time.sleep(0.1) | |
750 |
|
793 | |||
751 |
def getecho |
|
794 | def getecho(self): | |
752 |
|
795 | '''This returns the terminal echo mode. This returns True if echo is | ||
753 | """This returns the terminal echo mode. This returns True if echo is |
|
|||
754 | on or False if echo is off. Child applications that are expecting you |
|
796 | on or False if echo is off. Child applications that are expecting you | |
755 |
to enter a password often set ECHO False. See waitnoecho(). |
|
797 | to enter a password often set ECHO False. See waitnoecho(). ''' | |
756 |
|
798 | |||
757 | attr = termios.tcgetattr(self.child_fd) |
|
799 | attr = termios.tcgetattr(self.child_fd) | |
758 | if attr[3] & termios.ECHO: |
|
800 | if attr[3] & termios.ECHO: | |
759 | return True |
|
801 | return True | |
760 | return False |
|
802 | return False | |
761 |
|
803 | |||
762 |
def setecho |
|
804 | def setecho(self, state): | |
763 |
|
805 | '''This sets the terminal echo mode on or off. Note that anything the | ||
764 | """This sets the terminal echo mode on or off. Note that anything the |
|
|||
765 | child sent before the echo will be lost, so you should be sure that |
|
806 | child sent before the echo will be lost, so you should be sure that | |
766 | your input buffer is empty before you call setecho(). For example, the |
|
807 | your input buffer is empty before you call setecho(). For example, the | |
767 | following will work as expected:: |
|
808 | following will work as expected:: | |
768 |
|
809 | |||
769 | p = pexpect.spawn('cat') |
|
810 | p = pexpect.spawn('cat') # Echo is on by default. | |
770 |
p.sendline |
|
811 | p.sendline('1234') # We expect see this twice from the child... | |
771 |
p.expect |
|
812 | p.expect(['1234']) # ... once from the tty echo... | |
772 |
p.expect |
|
813 | p.expect(['1234']) # ... and again from cat itself. | |
773 | p.setecho(False) # Turn off tty echo |
|
814 | p.setecho(False) # Turn off tty echo | |
774 |
p.sendline |
|
815 | p.sendline('abcd') # We will set this only once (echoed by cat). | |
775 |
p.sendline |
|
816 | p.sendline('wxyz') # We will set this only once (echoed by cat) | |
776 |
p.expect |
|
817 | p.expect(['abcd']) | |
777 |
p.expect |
|
818 | p.expect(['wxyz']) | |
778 |
|
819 | |||
779 | The following WILL NOT WORK because the lines sent before the setecho |
|
820 | The following WILL NOT WORK because the lines sent before the setecho | |
780 | will be lost:: |
|
821 | will be lost:: | |
781 |
|
822 | |||
782 | p = pexpect.spawn('cat') |
|
823 | p = pexpect.spawn('cat') | |
783 | p.sendline ('1234') # We will see this twice (once from tty echo and again from cat). |
|
824 | p.sendline('1234') | |
784 | p.setecho(False) # Turn off tty echo |
|
825 | p.setecho(False) # Turn off tty echo | |
785 |
p.sendline |
|
826 | p.sendline('abcd') # We will set this only once (echoed by cat). | |
786 |
p.sendline |
|
827 | p.sendline('wxyz') # We will set this only once (echoed by cat) | |
787 |
p.expect |
|
828 | p.expect(['1234']) | |
788 |
p.expect |
|
829 | p.expect(['1234']) | |
789 |
p.expect |
|
830 | p.expect(['abcd']) | |
790 |
p.expect |
|
831 | p.expect(['wxyz']) | |
791 |
|
|
832 | ''' | |
792 |
|
833 | |||
793 | self.child_fd |
|
834 | self.child_fd | |
794 | attr = termios.tcgetattr(self.child_fd) |
|
835 | attr = termios.tcgetattr(self.child_fd) | |
@@ -796,22 +837,31 b' class spawnb(object):' | |||||
796 | attr[3] = attr[3] | termios.ECHO |
|
837 | attr[3] = attr[3] | termios.ECHO | |
797 | else: |
|
838 | else: | |
798 | attr[3] = attr[3] & ~termios.ECHO |
|
839 | attr[3] = attr[3] & ~termios.ECHO | |
799 |
# I tried TCSADRAIN and TCSAFLUSH, but |
|
840 | # I tried TCSADRAIN and TCSAFLUSH, but | |
800 | # and blocked on some platforms. TCSADRAIN is probably ideal if it worked. |
|
841 | # these were inconsistent and blocked on some platforms. | |
|
842 | # TCSADRAIN would probably be ideal if it worked. | |||
801 | termios.tcsetattr(self.child_fd, termios.TCSANOW, attr) |
|
843 | termios.tcsetattr(self.child_fd, termios.TCSANOW, attr) | |
802 |
|
844 | |||
803 |
def |
|
845 | def _log(self, s, direction): | |
|
846 | if self.logfile is not None: | |||
|
847 | self.logfile.write(s) | |||
|
848 | self.logfile.flush() | |||
|
849 | second_log = self.logfile_send if (direction=='send') else self.logfile_read | |||
|
850 | if second_log is not None: | |||
|
851 | second_log.write(s) | |||
|
852 | second_log.flush() | |||
804 |
|
853 | |||
805 | """This reads at most size bytes from the child application. It |
|
854 | def read_nonblocking(self, size=1, timeout=-1): | |
|
855 | '''This reads at most size characters from the child application. It | |||
806 | includes a timeout. If the read does not complete within the timeout |
|
856 | includes a timeout. If the read does not complete within the timeout | |
807 | period then a TIMEOUT exception is raised. If the end of file is read |
|
857 | period then a TIMEOUT exception is raised. If the end of file is read | |
808 | then an EOF exception will be raised. If a log file was set using |
|
858 | then an EOF exception will be raised. If a log file was set using | |
809 | setlog() then all data will also be written to the log file. |
|
859 | setlog() then all data will also be written to the log file. | |
810 |
|
860 | |||
811 |
If timeout is None then the read may block indefinitely. |
|
861 | If timeout is None then the read may block indefinitely. | |
812 |
then the self.timeout value is used. If timeout is 0 |
|
862 | If timeout is -1 then the self.timeout value is used. If timeout is 0 | |
813 |
polled and if there |
|
863 | then the child is polled and if there is no data immediately ready | |
814 | a TIMEOUT exception. |
|
864 | then this will raise a TIMEOUT exception. | |
815 |
|
865 | |||
816 | The timeout refers only to the amount of time to read at least one |
|
866 | The timeout refers only to the amount of time to read at least one | |
817 | character. This is not effected by the 'size' parameter, so if you call |
|
867 | character. This is not effected by the 'size' parameter, so if you call | |
@@ -820,10 +870,10 b' class spawnb(object):' | |||||
820 | It will not wait for 30 seconds for another 99 characters to come in. |
|
870 | It will not wait for 30 seconds for another 99 characters to come in. | |
821 |
|
871 | |||
822 | This is a wrapper around os.read(). It uses select.select() to |
|
872 | This is a wrapper around os.read(). It uses select.select() to | |
823 |
implement the timeout. |
|
873 | implement the timeout. ''' | |
824 |
|
874 | |||
825 | if self.closed: |
|
875 | if self.closed: | |
826 |
raise ValueError |
|
876 | raise ValueError('I/O operation on closed file.') | |
827 |
|
877 | |||
828 | if timeout == -1: |
|
878 | if timeout == -1: | |
829 | timeout = self.timeout |
|
879 | timeout = self.timeout | |
@@ -834,62 +884,62 b' class spawnb(object):' | |||||
834 | # For this case, I test isalive() before doing any reading. |
|
884 | # For this case, I test isalive() before doing any reading. | |
835 | # If isalive() is false, then I pretend that this is the same as EOF. |
|
885 | # If isalive() is false, then I pretend that this is the same as EOF. | |
836 | if not self.isalive(): |
|
886 | if not self.isalive(): | |
837 |
|
|
887 | # timeout of 0 means "poll" | |
|
888 | r, w, e = self.__select([self.child_fd], [], [], 0) | |||
838 | if not r: |
|
889 | if not r: | |
839 | self.flag_eof = True |
|
890 | self.flag_eof = True | |
840 |
raise EOF |
|
891 | raise EOF('End Of File (EOF). Braindead platform.') | |
841 | elif self.__irix_hack: |
|
892 | elif self.__irix_hack: | |
842 | # This is a hack for Irix. It seems that Irix requires a long delay before checking isalive. |
|
893 | # Irix takes a long time before it realizes a child was terminated. | |
843 | # This adds a 2 second delay, but only when the child is terminated. |
|
894 | # FIXME So does this mean Irix systems are forced to always have | |
|
895 | # FIXME a 2 second delay when calling read_nonblocking? That sucks. | |||
844 | r, w, e = self.__select([self.child_fd], [], [], 2) |
|
896 | r, w, e = self.__select([self.child_fd], [], [], 2) | |
845 | if not r and not self.isalive(): |
|
897 | if not r and not self.isalive(): | |
846 | self.flag_eof = True |
|
898 | self.flag_eof = True | |
847 |
raise EOF |
|
899 | raise EOF('End Of File (EOF). Slow platform.') | |
848 |
|
900 | |||
849 | r,w,e = self.__select([self.child_fd], [], [], timeout) |
|
901 | r, w, e = self.__select([self.child_fd], [], [], timeout) | |
850 |
|
902 | |||
851 | if not r: |
|
903 | if not r: | |
852 | if not self.isalive(): |
|
904 | if not self.isalive(): | |
853 |
# Some platforms, such as Irix, will claim that their |
|
905 | # Some platforms, such as Irix, will claim that their | |
854 | # then timeout on the select; and then finally admit that they are not alive. |
|
906 | # processes are alive; timeout on the select; and | |
|
907 | # then finally admit that they are not alive. | |||
855 | self.flag_eof = True |
|
908 | self.flag_eof = True | |
856 |
raise EOF |
|
909 | raise EOF('End of File (EOF). Very slow platform.') | |
857 | else: |
|
910 | else: | |
858 |
raise TIMEOUT |
|
911 | raise TIMEOUT('Timeout exceeded.') | |
859 |
|
912 | |||
860 | if self.child_fd in r: |
|
913 | if self.child_fd in r: | |
861 | try: |
|
914 | try: | |
862 | s = os.read(self.child_fd, size) |
|
915 | s = os.read(self.child_fd, size) | |
863 |
except OSError |
|
916 | except OSError: | |
|
917 | # Linux does this | |||
864 | self.flag_eof = True |
|
918 | self.flag_eof = True | |
865 |
raise EOF |
|
919 | raise EOF('End Of File (EOF). Exception style platform.') | |
866 |
if s == b'': |
|
920 | if s == b'': | |
|
921 | # BSD style | |||
867 | self.flag_eof = True |
|
922 | self.flag_eof = True | |
868 |
raise EOF |
|
923 | raise EOF('End Of File (EOF). Empty string style platform.') | |
869 |
|
||||
870 | s2 = self._cast_buffer_type(s) |
|
|||
871 | if self.logfile is not None: |
|
|||
872 | self.logfile.write(s2) |
|
|||
873 | self.logfile.flush() |
|
|||
874 | if self.logfile_read is not None: |
|
|||
875 | self.logfile_read.write(s2) |
|
|||
876 | self.logfile_read.flush() |
|
|||
877 |
|
924 | |||
|
925 | s = self._coerce_read_string(s) | |||
|
926 | self._log(s, 'read') | |||
878 | return s |
|
927 | return s | |
879 |
|
928 | |||
880 |
raise ExceptionPexpect |
|
929 | raise ExceptionPexpect('Reached an unexpected state.') | |
881 |
|
930 | |||
882 |
def read |
|
931 | def read(self, size=-1): | |
883 |
|
|
932 | '''This reads at most "size" bytes from the file (less if the read hits | |
884 | EOF before obtaining size bytes). If the size argument is negative or |
|
933 | EOF before obtaining size bytes). If the size argument is negative or | |
885 | omitted, read all data until EOF is reached. The bytes are returned as |
|
934 | omitted, read all data until EOF is reached. The bytes are returned as | |
886 | a string object. An empty string is returned when EOF is encountered |
|
935 | a string object. An empty string is returned when EOF is encountered | |
887 |
immediately. |
|
936 | immediately. ''' | |
888 |
|
937 | |||
889 | if size == 0: |
|
938 | if size == 0: | |
890 |
return self. |
|
939 | return self.string_type() | |
891 | if size < 0: |
|
940 | if size < 0: | |
892 |
|
|
941 | # delimiter default is EOF | |
|
942 | self.expect(self.delimiter) | |||
893 | return self.before |
|
943 | return self.before | |
894 |
|
944 | |||
895 | # I could have done this more directly by not using expect(), but |
|
945 | # I could have done this more directly by not using expect(), but | |
@@ -899,57 +949,47 b' class spawnb(object):' | |||||
899 | # worry about if I have to later modify read() or expect(). |
|
949 | # worry about if I have to later modify read() or expect(). | |
900 | # Note, it's OK if size==-1 in the regex. That just means it |
|
950 | # Note, it's OK if size==-1 in the regex. That just means it | |
901 | # will never match anything in which case we stop only on EOF. |
|
951 | # will never match anything in which case we stop only on EOF. | |
902 | if self._buffer_type is bytes: |
|
952 | cre = re.compile(self._coerce_expect_string('.{%d}' % size), re.DOTALL) | |
903 | pat = (u'.{%d}' % size).encode('ascii') |
|
953 | # delimiter default is EOF | |
904 | else: |
|
954 | index = self.expect([cre, self.delimiter]) | |
905 | pat = u'.{%d}' % size |
|
|||
906 | cre = re.compile(pat, re.DOTALL) |
|
|||
907 | index = self.expect ([cre, self.delimiter]) # delimiter default is EOF |
|
|||
908 | if index == 0: |
|
955 | if index == 0: | |
909 |
|
|
956 | ### FIXME self.before should be ''. Should I assert this? | |
|
957 | return self.after | |||
910 | return self.before |
|
958 | return self.before | |
911 |
|
959 | |||
912 |
def readline(self, size |
|
960 | def readline(self, size=-1): | |
913 |
|
|
961 | '''This reads and returns one entire line. The newline at the end of | |
914 | in the string, but may be absent when a file ends with an incomplete |
|
962 | line is returned as part of the string, unless the file ends without a | |
915 | line. Note: This readline() looks for a \\r\\n pair even on UNIX |
|
963 | newline. An empty string is returned if EOF is encountered immediately. | |
916 | because this is what the pseudo tty device returns. So contrary to what |
|
964 | This looks for a newline as a CR/LF pair (\\r\\n) even on UNIX because | |
917 | you may expect you will receive the newline as \\r\\n. An empty string |
|
965 | this is what the pseudotty device returns. So contrary to what you may | |
918 | is returned when EOF is hit immediately. Currently, the size argument is |
|
966 | expect you will receive newlines as \\r\\n. | |
919 | mostly ignored, so this behavior is not standard for a file-like |
|
967 | ||
920 |
|
|
968 | If the size argument is 0 then an empty string is returned. In all | |
|
969 | other cases the size argument is ignored, which is not standard | |||
|
970 | behavior for a file-like object. ''' | |||
921 |
|
971 | |||
922 | if size == 0: |
|
972 | if size == 0: | |
923 |
return self. |
|
973 | return self.string_type() | |
924 | index = self.expect ([self._pty_newline, self.delimiter]) # delimiter default is EOF |
|
974 | # delimiter default is EOF | |
|
975 | index = self.expect([b'\r\n', self.delimiter]) | |||
925 | if index == 0: |
|
976 | if index == 0: | |
926 |
return self.before + |
|
977 | return self.before + b'\r\n' | |
927 | return self.before |
|
978 | else: | |
928 |
|
979 | return self.before | ||
929 | def __iter__ (self): # File-like object. |
|
|||
930 |
|
||||
931 | """This is to support iterators over a file-like object. |
|
|||
932 | """ |
|
|||
933 |
|
||||
934 | return self |
|
|||
935 |
|
||||
936 | def __next__ (self): # File-like object. |
|
|||
937 |
|
||||
938 | """This is to support iterators over a file-like object. |
|
|||
939 | """ |
|
|||
940 |
|
||||
941 | result = self.readline() |
|
|||
942 | if result == self._empty_buffer: |
|
|||
943 | raise StopIteration |
|
|||
944 | return result |
|
|||
945 |
|
||||
946 | if not PY3: |
|
|||
947 | next = __next__ # File-like object. |
|
|||
948 |
|
980 | |||
949 | def readlines (self, sizehint = -1): # File-like object. |
|
981 | def __iter__(self): | |
|
982 | '''This is to support iterators over a file-like object. | |||
|
983 | ''' | |||
|
984 | return iter(self.readline, self.string_type()) | |||
950 |
|
985 | |||
951 | """This reads until EOF using readline() and returns a list containing |
|
986 | def readlines(self, sizehint=-1): | |
952 | the lines thus read. The optional "sizehint" argument is ignored. """ |
|
987 | '''This reads until EOF using readline() and returns a list containing | |
|
988 | the lines thus read. The optional 'sizehint' argument is ignored. | |||
|
989 | Remember, because this reads until EOF that means the child | |||
|
990 | process should have closed its stdout. If you run this method on | |||
|
991 | a child that is still running with its stdout open then this | |||
|
992 | method will block until it timesout.''' | |||
953 |
|
993 | |||
954 | lines = [] |
|
994 | lines = [] | |
955 | while True: |
|
995 | while True: | |
@@ -959,86 +999,81 b' class spawnb(object):' | |||||
959 | lines.append(line) |
|
999 | lines.append(line) | |
960 | return lines |
|
1000 | return lines | |
961 |
|
1001 | |||
962 |
def write(self, s): |
|
1002 | def write(self, s): | |
963 |
|
1003 | '''This is similar to send() except that there is no return value. | ||
964 | """This is similar to send() except that there is no return value. |
|
1004 | ''' | |
965 | """ |
|
|||
966 |
|
||||
967 | self.send (s) |
|
|||
968 |
|
1005 | |||
969 | def writelines (self, sequence): # File-like object. |
|
1006 | self.send(s) | |
970 |
|
1007 | |||
971 | """This calls write() for each element in the sequence. The sequence |
|
1008 | def writelines(self, sequence): | |
|
1009 | '''This calls write() for each element in the sequence. The sequence | |||
972 | can be any iterable object producing strings, typically a list of |
|
1010 | can be any iterable object producing strings, typically a list of | |
973 | strings. This does not add line separators There is no return value. |
|
1011 | strings. This does not add line separators. There is no return value. | |
974 |
|
|
1012 | ''' | |
975 |
|
1013 | |||
976 | for s in sequence: |
|
1014 | for s in sequence: | |
977 |
self.write |
|
1015 | self.write(s) | |
978 |
|
1016 | |||
979 | def send(self, s): |
|
1017 | def send(self, s): | |
980 |
|
1018 | '''Sends string ``s`` to the child process, returning the number of | ||
981 | """This sends a string to the child process. This returns the number of |
|
1019 | bytes written. If a logfile is specified, a copy is written to that | |
982 | bytes written. If a log file was set then the data is also written to |
|
1020 | log. ''' | |
983 | the log. """ |
|
|||
984 |
|
1021 | |||
985 | time.sleep(self.delaybeforesend) |
|
1022 | time.sleep(self.delaybeforesend) | |
986 |
|
||||
987 | s2 = self._cast_buffer_type(s) |
|
|||
988 | if self.logfile is not None: |
|
|||
989 | self.logfile.write(s2) |
|
|||
990 | self.logfile.flush() |
|
|||
991 | if self.logfile_send is not None: |
|
|||
992 | self.logfile_send.write(s2) |
|
|||
993 | self.logfile_send.flush() |
|
|||
994 | c = os.write (self.child_fd, _cast_bytes(s, self.encoding)) |
|
|||
995 | return c |
|
|||
996 |
|
1023 | |||
997 | def sendline(self, s=''): |
|
1024 | s = self._coerce_send_string(s) | |
|
1025 | self._log(s, 'send') | |||
|
1026 | ||||
|
1027 | return self._send(s) | |||
998 |
|
1028 | |||
999 | """This is like send(), but it adds a line feed (os.linesep). This |
|
1029 | def _send(self, s): | |
1000 | returns the number of bytes written. """ |
|
1030 | return os.write(self.child_fd, s) | |
|
1031 | ||||
|
1032 | def sendline(self, s=''): | |||
|
1033 | '''Wraps send(), sending string ``s`` to child process, with os.linesep | |||
|
1034 | automatically appended. Returns number of bytes written. ''' | |||
1001 |
|
1035 | |||
1002 |
n = self.send |
|
1036 | n = self.send(s) | |
1003 |
n = n + self.send |
|
1037 | n = n + self.send(self.linesep) | |
1004 | return n |
|
1038 | return n | |
1005 |
|
1039 | |||
1006 | def sendcontrol(self, char): |
|
1040 | def sendcontrol(self, char): | |
1007 |
|
1041 | |||
1008 | """This sends a control character to the child such as Ctrl-C or |
|
1042 | '''Helper method that wraps send() with mnemonic access for sending control | |
1009 | Ctrl-D. For example, to send a Ctrl-G (ASCII 7):: |
|
1043 | character to the child (such as Ctrl-C or Ctrl-D). For example, to send | |
|
1044 | Ctrl-G (ASCII 7, bell, '\a'):: | |||
1010 |
|
1045 | |||
1011 | child.sendcontrol('g') |
|
1046 | child.sendcontrol('g') | |
1012 |
|
1047 | |||
1013 | See also, sendintr() and sendeof(). |
|
1048 | See also, sendintr() and sendeof(). | |
1014 |
|
|
1049 | ''' | |
1015 |
|
1050 | |||
1016 | char = char.lower() |
|
1051 | char = char.lower() | |
1017 | a = ord(char) |
|
1052 | a = ord(char) | |
1018 | if a>=97 and a<=122: |
|
1053 | if a >= 97 and a <= 122: | |
1019 | a = a - ord('a') + 1 |
|
1054 | a = a - ord('a') + 1 | |
1020 |
return self.send |
|
1055 | return self.send(self._chr(a)) | |
1021 | d = {'@':0, '`':0, |
|
1056 | d = {'@': 0, '`': 0, | |
1022 | '[':27, '{':27, |
|
1057 | '[': 27, '{': 27, | |
1023 | '\\':28, '|':28, |
|
1058 | '\\': 28, '|': 28, | |
1024 | ']':29, '}': 29, |
|
1059 | ']': 29, '}': 29, | |
1025 | '^':30, '~':30, |
|
1060 | '^': 30, '~': 30, | |
1026 | '_':31, |
|
1061 | '_': 31, | |
1027 | '?':127} |
|
1062 | '?': 127} | |
1028 | if char not in d: |
|
1063 | if char not in d: | |
1029 | return 0 |
|
1064 | return 0 | |
1030 |
return self.send |
|
1065 | return self.send(self._chr(d[char])) | |
1031 |
|
1066 | |||
1032 | def sendeof(self): |
|
1067 | def sendeof(self): | |
1033 |
|
1068 | |||
1034 |
|
|
1069 | '''This sends an EOF to the child. This sends a character which causes | |
1035 | the pending parent output buffer to be sent to the waiting child |
|
1070 | the pending parent output buffer to be sent to the waiting child | |
1036 | program without waiting for end-of-line. If it is the first character |
|
1071 | program without waiting for end-of-line. If it is the first character | |
1037 | of the line, the read() in the user program returns 0, which signifies |
|
1072 | of the line, the read() in the user program returns 0, which signifies | |
1038 | end-of-file. This means to work as expected a sendeof() has to be |
|
1073 | end-of-file. This means to work as expected a sendeof() has to be | |
1039 | called at the beginning of a line. This method does not send a newline. |
|
1074 | called at the beginning of a line. This method does not send a newline. | |
1040 | It is the responsibility of the caller to ensure the eof is sent at the |
|
1075 | It is the responsibility of the caller to ensure the eof is sent at the | |
1041 |
beginning of a line. |
|
1076 | beginning of a line. ''' | |
1042 |
|
1077 | |||
1043 | ### Hmmm... how do I send an EOF? |
|
1078 | ### Hmmm... how do I send an EOF? | |
1044 | ###C if ((m = write(pty, *buf, p - *buf)) < 0) |
|
1079 | ###C if ((m = write(pty, *buf, p - *buf)) < 0) | |
@@ -1046,48 +1081,48 b' class spawnb(object):' | |||||
1046 | #fd = sys.stdin.fileno() |
|
1081 | #fd = sys.stdin.fileno() | |
1047 | #old = termios.tcgetattr(fd) # remember current state |
|
1082 | #old = termios.tcgetattr(fd) # remember current state | |
1048 | #attr = termios.tcgetattr(fd) |
|
1083 | #attr = termios.tcgetattr(fd) | |
1049 |
#attr[3] = attr[3] | termios.ICANON # ICANON must be set to |
|
1084 | #attr[3] = attr[3] | termios.ICANON # ICANON must be set to see EOF | |
1050 | #try: # use try/finally to ensure state gets restored |
|
1085 | #try: # use try/finally to ensure state gets restored | |
1051 | # termios.tcsetattr(fd, termios.TCSADRAIN, attr) |
|
1086 | # termios.tcsetattr(fd, termios.TCSADRAIN, attr) | |
1052 | # if hasattr(termios, 'CEOF'): |
|
1087 | # if hasattr(termios, 'CEOF'): | |
1053 |
# os.write |
|
1088 | # os.write(self.child_fd, '%c' % termios.CEOF) | |
1054 | # else: |
|
1089 | # else: | |
1055 | # # Silly platform does not define CEOF so assume CTRL-D |
|
1090 | # # Silly platform does not define CEOF so assume CTRL-D | |
1056 |
# os.write |
|
1091 | # os.write(self.child_fd, '%c' % 4) | |
1057 | #finally: # restore state |
|
1092 | #finally: # restore state | |
1058 | # termios.tcsetattr(fd, termios.TCSADRAIN, old) |
|
1093 | # termios.tcsetattr(fd, termios.TCSADRAIN, old) | |
1059 | if hasattr(termios, 'VEOF'): |
|
1094 | if hasattr(termios, 'VEOF'): | |
1060 | char = termios.tcgetattr(self.child_fd)[6][termios.VEOF] |
|
1095 | char = ord(termios.tcgetattr(self.child_fd)[6][termios.VEOF]) | |
1061 | else: |
|
1096 | else: | |
1062 | # platform does not define VEOF so assume CTRL-D |
|
1097 | # platform does not define VEOF so assume CTRL-D | |
1063 |
char = |
|
1098 | char = 4 | |
1064 | self.send(char) |
|
1099 | self.send(self._chr(char)) | |
1065 |
|
1100 | |||
1066 | def sendintr(self): |
|
1101 | def sendintr(self): | |
1067 |
|
1102 | |||
1068 |
|
|
1103 | '''This sends a SIGINT to the child. It does not require | |
1069 |
the SIGINT to be the first character on a line. |
|
1104 | the SIGINT to be the first character on a line. ''' | |
1070 |
|
1105 | |||
1071 | if hasattr(termios, 'VINTR'): |
|
1106 | if hasattr(termios, 'VINTR'): | |
1072 | char = termios.tcgetattr(self.child_fd)[6][termios.VINTR] |
|
1107 | char = ord(termios.tcgetattr(self.child_fd)[6][termios.VINTR]) | |
1073 | else: |
|
1108 | else: | |
1074 | # platform does not define VINTR so assume CTRL-C |
|
1109 | # platform does not define VINTR so assume CTRL-C | |
1075 |
char = |
|
1110 | char = 3 | |
1076 |
self.send |
|
1111 | self.send(self._chr(char)) | |
1077 |
|
1112 | |||
1078 |
def eof |
|
1113 | def eof(self): | |
1079 |
|
1114 | |||
1080 |
|
|
1115 | '''This returns True if the EOF exception was ever raised. | |
1081 |
|
|
1116 | ''' | |
1082 |
|
1117 | |||
1083 | return self.flag_eof |
|
1118 | return self.flag_eof | |
1084 |
|
1119 | |||
1085 | def terminate(self, force=False): |
|
1120 | def terminate(self, force=False): | |
1086 |
|
1121 | |||
1087 |
|
|
1122 | '''This forces a child process to terminate. It starts nicely with | |
1088 | SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This |
|
1123 | SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This | |
1089 | returns True if the child was terminated. This returns False if the |
|
1124 | returns True if the child was terminated. This returns False if the | |
1090 |
child could not be terminated. |
|
1125 | child could not be terminated. ''' | |
1091 |
|
1126 | |||
1092 | if not self.isalive(): |
|
1127 | if not self.isalive(): | |
1093 | return True |
|
1128 | return True | |
@@ -1112,7 +1147,7 b' class spawnb(object):' | |||||
1112 | else: |
|
1147 | else: | |
1113 | return False |
|
1148 | return False | |
1114 | return False |
|
1149 | return False | |
1115 |
except OSError |
|
1150 | except OSError: | |
1116 | # I think there are kernel timing issues that sometimes cause |
|
1151 | # I think there are kernel timing issues that sometimes cause | |
1117 | # this to happen. I think isalive() reports True, but the |
|
1152 | # this to happen. I think isalive() reports True, but the | |
1118 | # process is dead to the kernel. |
|
1153 | # process is dead to the kernel. | |
@@ -1125,107 +1160,136 b' class spawnb(object):' | |||||
1125 |
|
1160 | |||
1126 | def wait(self): |
|
1161 | def wait(self): | |
1127 |
|
1162 | |||
1128 |
|
|
1163 | '''This waits until the child exits. This is a blocking call. This will | |
1129 | not read any data from the child, so this will block forever if the |
|
1164 | not read any data from the child, so this will block forever if the | |
1130 | child has unread output and has terminated. In other words, the child |
|
1165 | child has unread output and has terminated. In other words, the child | |
1131 |
may have printed output then called exit() |
|
1166 | may have printed output then called exit(), but, the child is | |
1132 |
|
|
1167 | technically still alive until its output is read by the parent. ''' | |
1133 |
|
1168 | |||
1134 | if self.isalive(): |
|
1169 | if self.isalive(): | |
1135 | pid, status = os.waitpid(self.pid, 0) |
|
1170 | pid, status = os.waitpid(self.pid, 0) | |
1136 | else: |
|
1171 | else: | |
1137 |
raise ExceptionPexpect |
|
1172 | raise ExceptionPexpect('Cannot wait for dead child process.') | |
1138 | self.exitstatus = os.WEXITSTATUS(status) |
|
1173 | self.exitstatus = os.WEXITSTATUS(status) | |
1139 |
if os.WIFEXITED |
|
1174 | if os.WIFEXITED(status): | |
1140 | self.status = status |
|
1175 | self.status = status | |
1141 | self.exitstatus = os.WEXITSTATUS(status) |
|
1176 | self.exitstatus = os.WEXITSTATUS(status) | |
1142 | self.signalstatus = None |
|
1177 | self.signalstatus = None | |
1143 | self.terminated = True |
|
1178 | self.terminated = True | |
1144 |
elif os.WIFSIGNALED |
|
1179 | elif os.WIFSIGNALED(status): | |
1145 | self.status = status |
|
1180 | self.status = status | |
1146 | self.exitstatus = None |
|
1181 | self.exitstatus = None | |
1147 | self.signalstatus = os.WTERMSIG(status) |
|
1182 | self.signalstatus = os.WTERMSIG(status) | |
1148 | self.terminated = True |
|
1183 | self.terminated = True | |
1149 |
elif os.WIFSTOPPED |
|
1184 | elif os.WIFSTOPPED(status): | |
1150 | raise ExceptionPexpect ('Wait was called for a child process that is stopped. This is not supported. Is some other process attempting job control with our child pid?') |
|
1185 | # You can't call wait() on a child process in the stopped state. | |
|
1186 | raise ExceptionPexpect('Called wait() on a stopped child ' + | |||
|
1187 | 'process. This is not supported. Is some other ' + | |||
|
1188 | 'process attempting job control with our child pid?') | |||
1151 | return self.exitstatus |
|
1189 | return self.exitstatus | |
1152 |
|
1190 | |||
1153 | def isalive(self): |
|
1191 | def isalive(self): | |
1154 |
|
1192 | |||
1155 |
|
|
1193 | '''This tests if the child process is running or not. This is | |
1156 | non-blocking. If the child was terminated then this will read the |
|
1194 | non-blocking. If the child was terminated then this will read the | |
1157 | exitstatus or signalstatus of the child. This returns True if the child |
|
1195 | exitstatus or signalstatus of the child. This returns True if the child | |
1158 | process appears to be running or False if not. It can take literally |
|
1196 | process appears to be running or False if not. It can take literally | |
1159 |
SECONDS for Solaris to return the right status. |
|
1197 | SECONDS for Solaris to return the right status. ''' | |
1160 |
|
1198 | |||
1161 | if self.terminated: |
|
1199 | if self.terminated: | |
1162 | return False |
|
1200 | return False | |
1163 |
|
1201 | |||
1164 | if self.flag_eof: |
|
1202 | if self.flag_eof: | |
1165 |
# This is for Linux, which requires the blocking form |
|
1203 | # This is for Linux, which requires the blocking form | |
1166 | # status of a defunct process. This is super-lame. The flag_eof would have |
|
1204 | # of waitpid to # get status of a defunct process. | |
1167 | # been set in read_nonblocking(), so this should be safe. |
|
1205 | # This is super-lame. The flag_eof would have been set | |
|
1206 | # in read_nonblocking(), so this should be safe. | |||
1168 | waitpid_options = 0 |
|
1207 | waitpid_options = 0 | |
1169 | else: |
|
1208 | else: | |
1170 | waitpid_options = os.WNOHANG |
|
1209 | waitpid_options = os.WNOHANG | |
1171 |
|
1210 | |||
1172 | try: |
|
1211 | try: | |
1173 | pid, status = os.waitpid(self.pid, waitpid_options) |
|
1212 | pid, status = os.waitpid(self.pid, waitpid_options) | |
1174 |
except OSError |
|
1213 | except OSError: | |
1175 | if e.errno == errno.ECHILD: |
|
1214 | err = sys.exc_info()[1] | |
1176 | raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?') |
|
1215 | # No child processes | |
|
1216 | if err.errno == errno.ECHILD: | |||
|
1217 | raise ExceptionPexpect('isalive() encountered condition ' + | |||
|
1218 | 'where "terminated" is 0, but there was no child ' + | |||
|
1219 | 'process. Did someone else call waitpid() ' + | |||
|
1220 | 'on our process?') | |||
1177 | else: |
|
1221 | else: | |
1178 | raise e |
|
1222 | raise err | |
1179 |
|
1223 | |||
1180 |
# I have to do this twice for Solaris. |
|
1224 | # I have to do this twice for Solaris. | |
1181 | # If waitpid() returns 0 it means that no child process wishes to |
|
1225 | # I can't even believe that I figured this out... | |
1182 | # report, and the value of status is undefined. |
|
1226 | # If waitpid() returns 0 it means that no child process | |
|
1227 | # wishes to report, and the value of status is undefined. | |||
1183 | if pid == 0: |
|
1228 | if pid == 0: | |
1184 | try: |
|
1229 | try: | |
1185 |
|
|
1230 | ### os.WNOHANG) # Solaris! | |
1186 | except OSError as e: # This should never happen... |
|
1231 | pid, status = os.waitpid(self.pid, waitpid_options) | |
1187 | if e[0] == errno.ECHILD: |
|
1232 | except OSError as e: | |
1188 | raise ExceptionPexpect ('isalive() encountered condition that should never happen. There was no child process. Did someone else call waitpid() on our process?') |
|
1233 | # This should never happen... | |
|
1234 | if e.errno == errno.ECHILD: | |||
|
1235 | raise ExceptionPexpect('isalive() encountered condition ' + | |||
|
1236 | 'that should never happen. There was no child ' + | |||
|
1237 | 'process. Did someone else call waitpid() ' + | |||
|
1238 | 'on our process?') | |||
1189 | else: |
|
1239 | else: | |
1190 |
raise |
|
1240 | raise | |
1191 |
|
1241 | |||
1192 | # If pid is still 0 after two calls to waitpid() then |
|
1242 | # If pid is still 0 after two calls to waitpid() then the process | |
1193 |
# |
|
1243 | # really is alive. This seems to work on all platforms, except for | |
1194 |
# |
|
1244 | # Irix which seems to require a blocking call on waitpid or select, | |
1195 | # take care of this situation (unfortunately, this requires waiting through the timeout). |
|
1245 | # so I let read_nonblocking take care of this situation | |
|
1246 | # (unfortunately, this requires waiting through the timeout). | |||
1196 | if pid == 0: |
|
1247 | if pid == 0: | |
1197 | return True |
|
1248 | return True | |
1198 |
|
1249 | |||
1199 | if pid == 0: |
|
1250 | if pid == 0: | |
1200 | return True |
|
1251 | return True | |
1201 |
|
1252 | |||
1202 |
if os.WIFEXITED |
|
1253 | if os.WIFEXITED(status): | |
1203 | self.status = status |
|
1254 | self.status = status | |
1204 | self.exitstatus = os.WEXITSTATUS(status) |
|
1255 | self.exitstatus = os.WEXITSTATUS(status) | |
1205 | self.signalstatus = None |
|
1256 | self.signalstatus = None | |
1206 | self.terminated = True |
|
1257 | self.terminated = True | |
1207 |
elif os.WIFSIGNALED |
|
1258 | elif os.WIFSIGNALED(status): | |
1208 | self.status = status |
|
1259 | self.status = status | |
1209 | self.exitstatus = None |
|
1260 | self.exitstatus = None | |
1210 | self.signalstatus = os.WTERMSIG(status) |
|
1261 | self.signalstatus = os.WTERMSIG(status) | |
1211 | self.terminated = True |
|
1262 | self.terminated = True | |
1212 |
elif os.WIFSTOPPED |
|
1263 | elif os.WIFSTOPPED(status): | |
1213 | 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?') |
|
1264 | raise ExceptionPexpect('isalive() encountered condition ' + | |
|
1265 | 'where child process is stopped. This is not ' + | |||
|
1266 | 'supported. Is some other process attempting ' + | |||
|
1267 | 'job control with our child pid?') | |||
1214 | return False |
|
1268 | return False | |
1215 |
|
1269 | |||
1216 | def kill(self, sig): |
|
1270 | def kill(self, sig): | |
1217 |
|
1271 | |||
1218 |
|
|
1272 | '''This sends the given signal to the child application. In keeping | |
1219 | with UNIX tradition it has a misleading name. It does not necessarily |
|
1273 | with UNIX tradition it has a misleading name. It does not necessarily | |
1220 |
kill the child unless you send the right signal. |
|
1274 | kill the child unless you send the right signal. ''' | |
1221 |
|
1275 | |||
1222 | # Same as os.kill, but the pid is given for you. |
|
1276 | # Same as os.kill, but the pid is given for you. | |
1223 | if self.isalive(): |
|
1277 | if self.isalive(): | |
1224 | os.kill(self.pid, sig) |
|
1278 | os.kill(self.pid, sig) | |
1225 |
|
1279 | |||
|
1280 | def _pattern_type_err(self, pattern): | |||
|
1281 | raise TypeError('got {badtype} ({badobj!r}) as pattern, must be one' | |||
|
1282 | ' of: {goodtypes}, pexpect.EOF, pexpect.TIMEOUT'\ | |||
|
1283 | .format(badtype=type(pattern), | |||
|
1284 | badobj=pattern, | |||
|
1285 | goodtypes=', '.join([str(ast)\ | |||
|
1286 | for ast in self.allowed_string_types]) | |||
|
1287 | ) | |||
|
1288 | ) | |||
|
1289 | ||||
1226 | def compile_pattern_list(self, patterns): |
|
1290 | def compile_pattern_list(self, patterns): | |
1227 |
|
1291 | |||
1228 |
|
|
1292 | '''This compiles a pattern-string or a list of pattern-strings. | |
1229 | Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of |
|
1293 | Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of | |
1230 | those. Patterns may also be None which results in an empty list (you |
|
1294 | those. Patterns may also be None which results in an empty list (you | |
1231 | might do this if waiting for an EOF or TIMEOUT condition without |
|
1295 | might do this if waiting for an EOF or TIMEOUT condition without | |
@@ -1246,42 +1310,35 b' class spawnb(object):' | |||||
1246 | ... |
|
1310 | ... | |
1247 | i = self.expect_list(clp, timeout) |
|
1311 | i = self.expect_list(clp, timeout) | |
1248 | ... |
|
1312 | ... | |
1249 |
|
|
1313 | ''' | |
1250 |
|
1314 | |||
1251 | if patterns is None: |
|
1315 | if patterns is None: | |
1252 | return [] |
|
1316 | return [] | |
1253 | if not isinstance(patterns, list): |
|
1317 | if not isinstance(patterns, list): | |
1254 | patterns = [patterns] |
|
1318 | patterns = [patterns] | |
1255 |
|
1319 | |||
1256 |
|
|
1320 | # Allow dot to match \n | |
|
1321 | compile_flags = re.DOTALL | |||
1257 | if self.ignorecase: |
|
1322 | if self.ignorecase: | |
1258 | compile_flags = compile_flags | re.IGNORECASE |
|
1323 | compile_flags = compile_flags | re.IGNORECASE | |
1259 | compiled_pattern_list = [] |
|
1324 | compiled_pattern_list = [] | |
1260 | for p in patterns: |
|
1325 | for idx, p in enumerate(patterns): | |
1261 |
if isinstance(p, |
|
1326 | if isinstance(p, self.allowed_string_types): | |
1262 |
p = self._c |
|
1327 | p = self._coerce_expect_string(p) | |
1263 | compiled_pattern_list.append(re.compile(p, compile_flags)) |
|
1328 | compiled_pattern_list.append(re.compile(p, compile_flags)) | |
1264 | elif p is EOF: |
|
1329 | elif p is EOF: | |
1265 | compiled_pattern_list.append(EOF) |
|
1330 | compiled_pattern_list.append(EOF) | |
1266 | elif p is TIMEOUT: |
|
1331 | elif p is TIMEOUT: | |
1267 | compiled_pattern_list.append(TIMEOUT) |
|
1332 | compiled_pattern_list.append(TIMEOUT) | |
1268 |
elif type(p) |
|
1333 | elif isinstance(p, type(re.compile(''))): | |
1269 | p = self._prepare_regex_pattern(p) |
|
|||
1270 | compiled_pattern_list.append(p) |
|
1334 | compiled_pattern_list.append(p) | |
1271 | else: |
|
1335 | else: | |
1272 | raise TypeError ('Argument must be one of StringTypes, EOF, TIMEOUT, SRE_Pattern, or a list of those type. %s' % str(type(p))) |
|
1336 | self._pattern_type_err(p) | |
1273 |
|
||||
1274 | return compiled_pattern_list |
|
1337 | return compiled_pattern_list | |
1275 |
|
||||
1276 | def _prepare_regex_pattern(self, p): |
|
|||
1277 | "Recompile unicode regexes as bytes regexes. Overridden in subclass." |
|
|||
1278 | if isinstance(p.pattern, unicode_type): |
|
|||
1279 | p = re.compile(p.pattern.encode('utf-8'), p.flags &~ re.UNICODE) |
|
|||
1280 | return p |
|
|||
1281 |
|
1338 | |||
1282 |
def expect(self, pattern, timeout |
|
1339 | def expect(self, pattern, timeout=-1, searchwindowsize=-1): | |
1283 |
|
1340 | |||
1284 |
|
|
1341 | '''This seeks through the stream until a pattern is matched. The | |
1285 | pattern is overloaded and may take several types. The pattern can be a |
|
1342 | pattern is overloaded and may take several types. The pattern can be a | |
1286 | StringType, EOF, a compiled re, or a list of any of those types. |
|
1343 | StringType, EOF, a compiled re, or a list of any of those types. | |
1287 | Strings will be compiled to re types. This returns the index into the |
|
1344 | Strings will be compiled to re types. This returns the index into the | |
@@ -1291,21 +1348,21 b' class spawnb(object):' | |||||
1291 | list. That will cause expect to match an EOF or TIMEOUT condition |
|
1348 | list. That will cause expect to match an EOF or TIMEOUT condition | |
1292 | instead of raising an exception. |
|
1349 | instead of raising an exception. | |
1293 |
|
1350 | |||
1294 |
If you pass a list of patterns and more than one matches, the first |
|
1351 | If you pass a list of patterns and more than one matches, the first | |
1295 |
in the stream is chosen. If more than one pattern matches at that |
|
1352 | match in the stream is chosen. If more than one pattern matches at that | |
1296 | the leftmost in the pattern list is chosen. For example:: |
|
1353 | point, the leftmost in the pattern list is chosen. For example:: | |
1297 |
|
1354 | |||
1298 | # the input is 'foobar' |
|
1355 | # the input is 'foobar' | |
1299 |
index = p.expect |
|
1356 | index = p.expect(['bar', 'foo', 'foobar']) | |
1300 |
# returns 1 |
|
1357 | # returns 1('foo') even though 'foobar' is a "better" match | |
1301 |
|
1358 | |||
1302 | Please note, however, that buffering can affect this behavior, since |
|
1359 | Please note, however, that buffering can affect this behavior, since | |
1303 | input arrives in unpredictable chunks. For example:: |
|
1360 | input arrives in unpredictable chunks. For example:: | |
1304 |
|
1361 | |||
1305 | # the input is 'foobar' |
|
1362 | # the input is 'foobar' | |
1306 |
index = p.expect |
|
1363 | index = p.expect(['foobar', 'foo']) | |
1307 |
# returns 0 |
|
1364 | # returns 0('foobar') if all input is available at once, | |
1308 |
# but returs 1 |
|
1365 | # but returs 1('foo') if parts of the final 'bar' arrive late | |
1309 |
|
1366 | |||
1310 | After a match is found the instance attributes 'before', 'after' and |
|
1367 | After a match is found the instance attributes 'before', 'after' and | |
1311 | 'match' will be set. You can see all the data read before the match in |
|
1368 | 'match' will be set. You can see all the data read before the match in | |
@@ -1322,7 +1379,7 b' class spawnb(object):' | |||||
1322 | exception type. The attribute 'match' will be None. This allows you to |
|
1379 | exception type. The attribute 'match' will be None. This allows you to | |
1323 | write code like this:: |
|
1380 | write code like this:: | |
1324 |
|
1381 | |||
1325 |
index = p.expect |
|
1382 | index = p.expect(['good', 'bad', pexpect.EOF, pexpect.TIMEOUT]) | |
1326 | if index == 0: |
|
1383 | if index == 0: | |
1327 | do_something() |
|
1384 | do_something() | |
1328 | elif index == 1: |
|
1385 | elif index == 1: | |
@@ -1335,7 +1392,7 b' class spawnb(object):' | |||||
1335 | instead of code like this:: |
|
1392 | instead of code like this:: | |
1336 |
|
1393 | |||
1337 | try: |
|
1394 | try: | |
1338 |
index = p.expect |
|
1395 | index = p.expect(['good', 'bad']) | |
1339 | if index == 0: |
|
1396 | if index == 0: | |
1340 | do_something() |
|
1397 | do_something() | |
1341 | elif index == 1: |
|
1398 | elif index == 1: | |
@@ -1350,32 +1407,34 b' class spawnb(object):' | |||||
1350 | child to finish. For example:: |
|
1407 | child to finish. For example:: | |
1351 |
|
1408 | |||
1352 | p = pexpect.spawn('/bin/ls') |
|
1409 | p = pexpect.spawn('/bin/ls') | |
1353 |
p.expect |
|
1410 | p.expect(pexpect.EOF) | |
1354 | print p.before |
|
1411 | print p.before | |
1355 |
|
1412 | |||
1356 | If you are trying to optimize for speed then see expect_list(). |
|
1413 | If you are trying to optimize for speed then see expect_list(). | |
1357 |
|
|
1414 | ''' | |
1358 |
|
1415 | |||
1359 | compiled_pattern_list = self.compile_pattern_list(pattern) |
|
1416 | compiled_pattern_list = self.compile_pattern_list(pattern) | |
1360 |
return self.expect_list(compiled_pattern_list, |
|
1417 | return self.expect_list(compiled_pattern_list, | |
|
1418 | timeout, searchwindowsize) | |||
1361 |
|
1419 | |||
1362 |
def expect_list(self, pattern_list, timeout |
|
1420 | def expect_list(self, pattern_list, timeout=-1, searchwindowsize=-1): | |
1363 |
|
1421 | |||
1364 |
|
|
1422 | '''This takes a list of compiled regular expressions and returns the | |
1365 | index into the pattern_list that matched the child output. The list may |
|
1423 | index into the pattern_list that matched the child output. The list may | |
1366 |
also contain EOF or TIMEOUT |
|
1424 | also contain EOF or TIMEOUT(which are not compiled regular | |
1367 | expressions). This method is similar to the expect() method except that |
|
1425 | expressions). This method is similar to the expect() method except that | |
1368 | expect_list() does not recompile the pattern list on every call. This |
|
1426 | expect_list() does not recompile the pattern list on every call. This | |
1369 | may help if you are trying to optimize for speed, otherwise just use |
|
1427 | may help if you are trying to optimize for speed, otherwise just use | |
1370 | the expect() method. This is called by expect(). If timeout==-1 then |
|
1428 | the expect() method. This is called by expect(). If timeout==-1 then | |
1371 | the self.timeout value is used. If searchwindowsize==-1 then the |
|
1429 | the self.timeout value is used. If searchwindowsize==-1 then the | |
1372 |
self.searchwindowsize value is used. |
|
1430 | self.searchwindowsize value is used. ''' | |
1373 |
|
1431 | |||
1374 |
return self.expect_loop(searcher_re(pattern_list), |
|
1432 | return self.expect_loop(searcher_re(pattern_list), | |
|
1433 | timeout, searchwindowsize) | |||
1375 |
|
1434 | |||
1376 |
def expect_exact(self, pattern_list, timeout |
|
1435 | def expect_exact(self, pattern_list, timeout=-1, searchwindowsize=-1): | |
1377 |
|
1436 | |||
1378 |
|
|
1437 | '''This is similar to expect(), but uses plain string matching instead | |
1379 | of compiled regular expressions in 'pattern_list'. The 'pattern_list' |
|
1438 | of compiled regular expressions in 'pattern_list'. The 'pattern_list' | |
1380 | may be a string; a list or other sequence of strings; or TIMEOUT and |
|
1439 | may be a string; a list or other sequence of strings; or TIMEOUT and | |
1381 | EOF. |
|
1440 | EOF. | |
@@ -1385,19 +1444,34 b' class spawnb(object):' | |||||
1385 | search to just the end of the input buffer. |
|
1444 | search to just the end of the input buffer. | |
1386 |
|
1445 | |||
1387 | This method is also useful when you don't want to have to worry about |
|
1446 | This method is also useful when you don't want to have to worry about | |
1388 |
escaping regular expression characters that you want to match. |
|
1447 | escaping regular expression characters that you want to match.''' | |
1389 |
|
1448 | |||
1390 | if isinstance(pattern_list, (bytes, unicode_type)) or pattern_list in (TIMEOUT, EOF): |
|
1449 | if (isinstance(pattern_list, self.allowed_string_types) or | |
|
1450 | pattern_list in (TIMEOUT, EOF)): | |||
1391 | pattern_list = [pattern_list] |
|
1451 | pattern_list = [pattern_list] | |
1392 | return self.expect_loop(searcher_string(pattern_list), timeout, searchwindowsize) |
|
|||
1393 |
|
1452 | |||
1394 | def expect_loop(self, searcher, timeout = -1, searchwindowsize = -1): |
|
1453 | def prepare_pattern(pattern): | |
|
1454 | if pattern in (TIMEOUT, EOF): | |||
|
1455 | return pattern | |||
|
1456 | if isinstance(pattern, self.allowed_string_types): | |||
|
1457 | return self._coerce_expect_string(pattern) | |||
|
1458 | self._pattern_type_err(pattern) | |||
1395 |
|
1459 | |||
1396 | """This is the common loop used inside expect. The 'searcher' should be |
|
1460 | try: | |
1397 | an instance of searcher_re or searcher_string, which describes how and what |
|
1461 | pattern_list = iter(pattern_list) | |
1398 | to search for in the input. |
|
1462 | except TypeError: | |
|
1463 | self._pattern_type_err(pattern_list) | |||
|
1464 | pattern_list = [prepare_pattern(p) for p in pattern_list] | |||
|
1465 | return self.expect_loop(searcher_string(pattern_list), | |||
|
1466 | timeout, searchwindowsize) | |||
|
1467 | ||||
|
1468 | def expect_loop(self, searcher, timeout=-1, searchwindowsize=-1): | |||
1399 |
|
1469 | |||
1400 | See expect() for other arguments, return value and exceptions. """ |
|
1470 | '''This is the common loop used inside expect. The 'searcher' should be | |
|
1471 | an instance of searcher_re or searcher_string, which describes how and | |||
|
1472 | what to search for in the input. | |||
|
1473 | ||||
|
1474 | See expect() for other arguments, return value and exceptions. ''' | |||
1401 |
|
1475 | |||
1402 | self.searcher = searcher |
|
1476 | self.searcher = searcher | |
1403 |
|
1477 | |||
@@ -1411,27 +1485,29 b' class spawnb(object):' | |||||
1411 | try: |
|
1485 | try: | |
1412 | incoming = self.buffer |
|
1486 | incoming = self.buffer | |
1413 | freshlen = len(incoming) |
|
1487 | freshlen = len(incoming) | |
1414 | while True: # Keep reading until exception or return. |
|
1488 | while True: | |
|
1489 | # Keep reading until exception or return. | |||
1415 | index = searcher.search(incoming, freshlen, searchwindowsize) |
|
1490 | index = searcher.search(incoming, freshlen, searchwindowsize) | |
1416 | if index >= 0: |
|
1491 | if index >= 0: | |
1417 |
self.buffer = incoming[searcher.end |
|
1492 | self.buffer = incoming[searcher.end:] | |
1418 |
self.before = incoming[ |
|
1493 | self.before = incoming[: searcher.start] | |
1419 |
self.after = incoming[searcher.start |
|
1494 | self.after = incoming[searcher.start: searcher.end] | |
1420 | self.match = searcher.match |
|
1495 | self.match = searcher.match | |
1421 | self.match_index = index |
|
1496 | self.match_index = index | |
1422 | return self.match_index |
|
1497 | return self.match_index | |
1423 | # No match at this point |
|
1498 | # No match at this point | |
1424 | if timeout is not None and timeout < 0: |
|
1499 | if (timeout is not None) and (timeout < 0): | |
1425 |
raise TIMEOUT |
|
1500 | raise TIMEOUT('Timeout exceeded in expect_any().') | |
1426 | # Still have time left, so read more data |
|
1501 | # Still have time left, so read more data | |
1427 |
c = self.read_nonblocking |
|
1502 | c = self.read_nonblocking(self.maxread, timeout) | |
1428 | freshlen = len(c) |
|
1503 | freshlen = len(c) | |
1429 |
time.sleep |
|
1504 | time.sleep(0.0001) | |
1430 | incoming = incoming + c |
|
1505 | incoming = incoming + c | |
1431 | if timeout is not None: |
|
1506 | if timeout is not None: | |
1432 | timeout = end_time - time.time() |
|
1507 | timeout = end_time - time.time() | |
1433 |
except EOF |
|
1508 | except EOF: | |
1434 | self.buffer = self._empty_buffer |
|
1509 | err = sys.exc_info()[1] | |
|
1510 | self.buffer = self.string_type() | |||
1435 | self.before = incoming |
|
1511 | self.before = incoming | |
1436 | self.after = EOF |
|
1512 | self.after = EOF | |
1437 | index = searcher.eof_index |
|
1513 | index = searcher.eof_index | |
@@ -1442,8 +1518,9 b' class spawnb(object):' | |||||
1442 | else: |
|
1518 | else: | |
1443 | self.match = None |
|
1519 | self.match = None | |
1444 | self.match_index = None |
|
1520 | self.match_index = None | |
1445 |
raise EOF |
|
1521 | raise EOF(str(err) + '\n' + str(self)) | |
1446 |
except TIMEOUT |
|
1522 | except TIMEOUT: | |
|
1523 | err = sys.exc_info()[1] | |||
1447 | self.buffer = incoming |
|
1524 | self.buffer = incoming | |
1448 | self.before = incoming |
|
1525 | self.before = incoming | |
1449 | self.after = TIMEOUT |
|
1526 | self.after = TIMEOUT | |
@@ -1455,7 +1532,7 b' class spawnb(object):' | |||||
1455 | else: |
|
1532 | else: | |
1456 | self.match = None |
|
1533 | self.match = None | |
1457 | self.match_index = None |
|
1534 | self.match_index = None | |
1458 |
raise TIMEOUT |
|
1535 | raise TIMEOUT(str(err) + '\n' + str(self)) | |
1459 | except: |
|
1536 | except: | |
1460 | self.before = incoming |
|
1537 | self.before = incoming | |
1461 | self.after = None |
|
1538 | self.after = None | |
@@ -1465,40 +1542,35 b' class spawnb(object):' | |||||
1465 |
|
1542 | |||
1466 | def getwinsize(self): |
|
1543 | def getwinsize(self): | |
1467 |
|
1544 | |||
1468 |
|
|
1545 | '''This returns the terminal window size of the child tty. The return | |
1469 |
value is a tuple of (rows, cols). |
|
1546 | value is a tuple of (rows, cols). ''' | |
1470 |
|
1547 | |||
1471 | TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912) |
|
1548 | TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912) | |
1472 | s = struct.pack('HHHH', 0, 0, 0, 0) |
|
1549 | s = struct.pack('HHHH', 0, 0, 0, 0) | |
1473 |
x = fcntl.ioctl(self. |
|
1550 | x = fcntl.ioctl(self.child_fd, TIOCGWINSZ, s) | |
1474 | return struct.unpack('HHHH', x)[0:2] |
|
1551 | return struct.unpack('HHHH', x)[0:2] | |
1475 |
|
1552 | |||
1476 | def setwinsize(self, r, c): |
|
1553 | def setwinsize(self, rows, cols): | |
1477 |
|
1554 | |||
1478 |
|
|
1555 | '''This sets the terminal window size of the child tty. This will cause | |
1479 | a SIGWINCH signal to be sent to the child. This does not change the |
|
1556 | a SIGWINCH signal to be sent to the child. This does not change the | |
1480 | physical window size. It changes the size reported to TTY-aware |
|
1557 | physical window size. It changes the size reported to TTY-aware | |
1481 | applications like vi or curses -- applications that respond to the |
|
1558 | applications like vi or curses -- applications that respond to the | |
1482 |
SIGWINCH signal. |
|
1559 | SIGWINCH signal. ''' | |
1483 |
|
1560 | |||
1484 | # Check for buggy platforms. Some Python versions on some platforms |
|
1561 | # Some very old platforms have a bug that causes the value for | |
1485 | # (notably OSF1 Alpha and RedHat 7.1) truncate the value for |
|
1562 | # termios.TIOCSWINSZ to be truncated. There was a hack here to work | |
1486 | # termios.TIOCSWINSZ. It is not clear why this happens. |
|
1563 | # around this, but it caused problems with newer platforms so has been | |
1487 | # These platforms don't seem to handle the signed int very well; |
|
1564 | # removed. For details see https://github.com/pexpect/pexpect/issues/39 | |
1488 | # yet other platforms like OpenBSD have a large negative value for |
|
|||
1489 | # TIOCSWINSZ and they don't have a truncate problem. |
|
|||
1490 | # Newer versions of Linux have totally different values for TIOCSWINSZ. |
|
|||
1491 | # Note that this fix is a hack. |
|
|||
1492 | TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561) |
|
1565 | TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561) | |
1493 | if TIOCSWINSZ == 2148037735: # L is not required in Python >= 2.2. |
|
|||
1494 | TIOCSWINSZ = -2146929561 # Same bits, but with sign. |
|
|||
1495 | # Note, assume ws_xpixel and ws_ypixel are zero. |
|
1566 | # Note, assume ws_xpixel and ws_ypixel are zero. | |
1496 | s = struct.pack('HHHH', r, c, 0, 0) |
|
1567 | s = struct.pack('HHHH', rows, cols, 0, 0) | |
1497 | fcntl.ioctl(self.fileno(), TIOCSWINSZ, s) |
|
1568 | fcntl.ioctl(self.fileno(), TIOCSWINSZ, s) | |
1498 |
|
1569 | |||
1499 | def interact(self, escape_character = b'\x1d', input_filter = None, output_filter = None): |
|
1570 | def interact(self, escape_character=chr(29), | |
|
1571 | input_filter=None, output_filter=None): | |||
1500 |
|
1572 | |||
1501 |
|
|
1573 | '''This gives control of the child process to the interactive user (the | |
1502 | human at the keyboard). Keystrokes are sent to the child process, and |
|
1574 | human at the keyboard). Keystrokes are sent to the child process, and | |
1503 | the stdout and stderr output of the child process is printed. This |
|
1575 | the stdout and stderr output of the child process is printed. This | |
1504 | simply echos the child stdout and child stderr to the real stdout and |
|
1576 | simply echos the child stdout and child stderr to the real stdout and | |
@@ -1523,59 +1595,68 b' class spawnb(object):' | |||||
1523 | import pexpect, struct, fcntl, termios, signal, sys |
|
1595 | import pexpect, struct, fcntl, termios, signal, sys | |
1524 | def sigwinch_passthrough (sig, data): |
|
1596 | def sigwinch_passthrough (sig, data): | |
1525 | s = struct.pack("HHHH", 0, 0, 0, 0) |
|
1597 | s = struct.pack("HHHH", 0, 0, 0, 0) | |
1526 |
a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), |
|
1598 | a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), | |
|
1599 | termios.TIOCGWINSZ , s)) | |||
1527 | global p |
|
1600 | global p | |
1528 | p.setwinsize(a[0],a[1]) |
|
1601 | p.setwinsize(a[0],a[1]) | |
1529 |
|
|
1602 | # Note this 'p' global and used in sigwinch_passthrough. | |
|
1603 | p = pexpect.spawn('/bin/bash') | |||
1530 | signal.signal(signal.SIGWINCH, sigwinch_passthrough) |
|
1604 | signal.signal(signal.SIGWINCH, sigwinch_passthrough) | |
1531 | p.interact() |
|
1605 | p.interact() | |
1532 |
|
|
1606 | ''' | |
1533 |
|
1607 | |||
1534 | # Flush the buffer. |
|
1608 | # Flush the buffer. | |
1535 | if PY3: self.stdout.write(_cast_unicode(self.buffer, self.encoding)) |
|
1609 | self.write_to_stdout(self.buffer) | |
1536 | else: self.stdout.write(self.buffer) |
|
|||
1537 | self.stdout.flush() |
|
1610 | self.stdout.flush() | |
1538 |
self.buffer = self. |
|
1611 | self.buffer = self.string_type() | |
1539 | mode = tty.tcgetattr(self.STDIN_FILENO) |
|
1612 | mode = tty.tcgetattr(self.STDIN_FILENO) | |
1540 | tty.setraw(self.STDIN_FILENO) |
|
1613 | tty.setraw(self.STDIN_FILENO) | |
|
1614 | if PY3: | |||
|
1615 | escape_character = escape_character.encode('latin-1') | |||
1541 | try: |
|
1616 | try: | |
1542 | self.__interact_copy(escape_character, input_filter, output_filter) |
|
1617 | self.__interact_copy(escape_character, input_filter, output_filter) | |
1543 | finally: |
|
1618 | finally: | |
1544 | tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode) |
|
1619 | tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode) | |
1545 |
|
1620 | |||
1546 | def __interact_writen(self, fd, data): |
|
1621 | def __interact_writen(self, fd, data): | |
1547 |
|
1622 | '''This is used by the interact() method. | ||
1548 | """This is used by the interact() method. |
|
1623 | ''' | |
1549 | """ |
|
|||
1550 |
|
1624 | |||
1551 | while data != b'' and self.isalive(): |
|
1625 | while data != b'' and self.isalive(): | |
1552 | n = os.write(fd, data) |
|
1626 | n = os.write(fd, data) | |
1553 | data = data[n:] |
|
1627 | data = data[n:] | |
1554 |
|
1628 | |||
1555 | def __interact_read(self, fd): |
|
1629 | def __interact_read(self, fd): | |
1556 |
|
1630 | '''This is used by the interact() method. | ||
1557 | """This is used by the interact() method. |
|
1631 | ''' | |
1558 | """ |
|
|||
1559 |
|
1632 | |||
1560 | return os.read(fd, 1000) |
|
1633 | return os.read(fd, 1000) | |
1561 |
|
1634 | |||
1562 |
def __interact_copy(self, escape_character |
|
1635 | def __interact_copy(self, escape_character=None, | |
|
1636 | input_filter=None, output_filter=None): | |||
1563 |
|
1637 | |||
1564 |
|
|
1638 | '''This is used by the interact() method. | |
1565 |
|
|
1639 | ''' | |
1566 |
|
1640 | |||
1567 | while self.isalive(): |
|
1641 | while self.isalive(): | |
1568 | r,w,e = self.__select([self.child_fd, self.STDIN_FILENO], [], []) |
|
1642 | r, w, e = self.__select([self.child_fd, self.STDIN_FILENO], [], []) | |
1569 | if self.child_fd in r: |
|
1643 | if self.child_fd in r: | |
1570 | data = self.__interact_read(self.child_fd) |
|
1644 | try: | |
1571 | if output_filter: data = output_filter(data) |
|
1645 | data = self.__interact_read(self.child_fd) | |
|
1646 | except OSError as e: | |||
|
1647 | # The subprocess may have closed before we get to reading it | |||
|
1648 | if e.errno != errno.EIO: | |||
|
1649 | raise | |||
|
1650 | if output_filter: | |||
|
1651 | data = output_filter(data) | |||
1572 | if self.logfile is not None: |
|
1652 | if self.logfile is not None: | |
1573 |
self.logfile.write |
|
1653 | self.logfile.write(data) | |
1574 | self.logfile.flush() |
|
1654 | self.logfile.flush() | |
1575 | os.write(self.STDOUT_FILENO, data) |
|
1655 | os.write(self.STDOUT_FILENO, data) | |
1576 | if self.STDIN_FILENO in r: |
|
1656 | if self.STDIN_FILENO in r: | |
1577 | data = self.__interact_read(self.STDIN_FILENO) |
|
1657 | data = self.__interact_read(self.STDIN_FILENO) | |
1578 |
if input_filter: |
|
1658 | if input_filter: | |
|
1659 | data = input_filter(data) | |||
1579 | i = data.rfind(escape_character) |
|
1660 | i = data.rfind(escape_character) | |
1580 | if i != -1: |
|
1661 | if i != -1: | |
1581 | data = data[:i] |
|
1662 | data = data[:i] | |
@@ -1583,12 +1664,12 b' class spawnb(object):' | |||||
1583 | break |
|
1664 | break | |
1584 | self.__interact_writen(self.child_fd, data) |
|
1665 | self.__interact_writen(self.child_fd, data) | |
1585 |
|
1666 | |||
1586 |
def __select |
|
1667 | def __select(self, iwtd, owtd, ewtd, timeout=None): | |
1587 |
|
1668 | |||
1588 |
|
|
1669 | '''This is a wrapper around select.select() that ignores signals. If | |
1589 | select.select raises a select.error exception and errno is an EINTR |
|
1670 | select.select raises a select.error exception and errno is an EINTR | |
1590 | error then it is ignored. Mainly this is used to ignore sigwinch |
|
1671 | error then it is ignored. Mainly this is used to ignore sigwinch | |
1591 |
(terminal resize). |
|
1672 | (terminal resize). ''' | |
1592 |
|
1673 | |||
1593 | # if select() is interrupted by a signal (errno==EINTR) then |
|
1674 | # if select() is interrupted by a signal (errno==EINTR) then | |
1594 | # we loop back and enter the select() again. |
|
1675 | # we loop back and enter the select() again. | |
@@ -1596,53 +1677,93 b' class spawnb(object):' | |||||
1596 | end_time = time.time() + timeout |
|
1677 | end_time = time.time() + timeout | |
1597 | while True: |
|
1678 | while True: | |
1598 | try: |
|
1679 | try: | |
1599 |
return select.select |
|
1680 | return select.select(iwtd, owtd, ewtd, timeout) | |
1600 |
except select.error |
|
1681 | except select.error: | |
1601 | if e.args[0] == errno.EINTR: |
|
1682 | err = sys.exc_info()[1] | |
1602 | # if we loop back we have to subtract the amount of time we already waited. |
|
1683 | if err.args[0] == errno.EINTR: | |
|
1684 | # if we loop back we have to subtract the | |||
|
1685 | # amount of time we already waited. | |||
1603 | if timeout is not None: |
|
1686 | if timeout is not None: | |
1604 | timeout = end_time - time.time() |
|
1687 | timeout = end_time - time.time() | |
1605 | if timeout < 0: |
|
1688 | if timeout < 0: | |
1606 |
return |
|
1689 | return([], [], []) | |
1607 | else: # something else caused the select.error, so this really is an exception |
|
1690 | else: | |
|
1691 | # something else caused the select.error, so | |||
|
1692 | # this actually is an exception. | |||
1608 | raise |
|
1693 | raise | |
1609 |
|
1694 | |||
1610 | class spawn(spawnb): |
|
1695 | ############################################################################## | |
1611 | """This is the main class interface for Pexpect. Use this class to start |
|
1696 | # The following methods are no longer supported or allowed. | |
1612 | and control child applications.""" |
|
1697 | ||
1613 |
|
1698 | def setmaxread(self, maxread): | ||
1614 | _buffer_type = unicode_type |
|
1699 | ||
1615 | def _cast_buffer_type(self, s): |
|
1700 | '''This method is no longer supported or allowed. I don't like getters | |
1616 | return _cast_unicode(s, self.encoding) |
|
1701 | and setters without a good reason. ''' | |
1617 | _empty_buffer = u'' |
|
1702 | ||
1618 | _pty_newline = u'\r\n' |
|
1703 | raise ExceptionPexpect('This method is no longer supported ' + | |
1619 |
|
1704 | 'or allowed. Just assign a value to the ' + | ||
1620 | def __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize=None, |
|
1705 | 'maxread member variable.') | |
1621 | logfile=None, cwd=None, env=None, encoding='utf-8'): |
|
1706 | ||
1622 | super(spawn, self).__init__(command, args, timeout=timeout, maxread=maxread, |
|
1707 | def setlog(self, fileobject): | |
1623 | searchwindowsize=searchwindowsize, logfile=logfile, cwd=cwd, env=env) |
|
1708 | ||
1624 | self.encoding = encoding |
|
1709 | '''This method is no longer supported or allowed. | |
1625 |
|
1710 | ''' | ||
1626 | def _prepare_regex_pattern(self, p): |
|
1711 | ||
1627 | "Recompile bytes regexes as unicode regexes." |
|
1712 | raise ExceptionPexpect('This method is no longer supported ' + | |
1628 | if isinstance(p.pattern, bytes): |
|
1713 | 'or allowed. Just assign a value to the logfile ' + | |
1629 | p = re.compile(p.pattern.decode(self.encoding), p.flags) |
|
1714 | 'member variable.') | |
1630 | return p |
|
|||
1631 |
|
||||
1632 | def read_nonblocking(self, size=1, timeout=-1): |
|
|||
1633 | return super(spawn, self).read_nonblocking(size=size, timeout=timeout)\ |
|
|||
1634 | .decode(self.encoding) |
|
|||
1635 |
|
||||
1636 | read_nonblocking.__doc__ = spawnb.read_nonblocking.__doc__ |
|
|||
1637 |
|
||||
1638 |
|
1715 | |||
1639 | ############################################################################## |
|
1716 | ############################################################################## | |
1640 | # End of spawn class |
|
1717 | # End of spawn class | |
1641 | ############################################################################## |
|
1718 | ############################################################################## | |
1642 |
|
1719 | |||
1643 | class searcher_string (object): |
|
1720 | class spawnu(spawn): | |
|
1721 | """Works like spawn, but accepts and returns unicode strings. | |||
|
1722 | ||||
|
1723 | Extra parameters: | |||
|
1724 | ||||
|
1725 | :param encoding: The encoding to use for communications (default: 'utf-8') | |||
|
1726 | :param errors: How to handle encoding/decoding errors; one of 'strict' | |||
|
1727 | (the default), 'ignore', or 'replace', as described | |||
|
1728 | for :meth:`~bytes.decode` and :meth:`~str.encode`. | |||
|
1729 | """ | |||
|
1730 | if PY3: | |||
|
1731 | string_type = str | |||
|
1732 | allowed_string_types = (str, ) | |||
|
1733 | _chr = staticmethod(chr) | |||
|
1734 | linesep = os.linesep | |||
|
1735 | else: | |||
|
1736 | string_type = unicode | |||
|
1737 | allowed_string_types = (unicode, ) | |||
|
1738 | _chr = staticmethod(unichr) | |||
|
1739 | linesep = os.linesep.decode('ascii') | |||
|
1740 | # This can handle unicode in both Python 2 and 3 | |||
|
1741 | write_to_stdout = sys.stdout.write | |||
|
1742 | ||||
|
1743 | def __init__(self, *args, **kwargs): | |||
|
1744 | self.encoding = kwargs.pop('encoding', 'utf-8') | |||
|
1745 | self.errors = kwargs.pop('errors', 'strict') | |||
|
1746 | self._decoder = codecs.getincrementaldecoder(self.encoding)(errors=self.errors) | |||
|
1747 | super(spawnu, self).__init__(*args, **kwargs) | |||
|
1748 | ||||
|
1749 | @staticmethod | |||
|
1750 | def _coerce_expect_string(s): | |||
|
1751 | return s | |||
1644 |
|
1752 | |||
1645 | """This is a plain string search helper for the spawn.expect_any() method. |
|
1753 | @staticmethod | |
|
1754 | def _coerce_send_string(s): | |||
|
1755 | return s | |||
|
1756 | ||||
|
1757 | def _coerce_read_string(self, s): | |||
|
1758 | return self._decoder.decode(s, final=False) | |||
|
1759 | ||||
|
1760 | def _send(self, s): | |||
|
1761 | return os.write(self.child_fd, s.encode(self.encoding, self.errors)) | |||
|
1762 | ||||
|
1763 | ||||
|
1764 | class searcher_string(object): | |||
|
1765 | ||||
|
1766 | '''This is a plain string search helper for the spawn.expect_any() method. | |||
1646 | This helper class is for speed. For more powerful regex patterns |
|
1767 | This helper class is for speed. For more powerful regex patterns | |
1647 | see the helper class, searcher_re. |
|
1768 | see the helper class, searcher_re. | |
1648 |
|
1769 | |||
@@ -1658,12 +1779,12 b' class searcher_string (object):' | |||||
1658 | end - index into the buffer, first byte after match |
|
1779 | end - index into the buffer, first byte after match | |
1659 | match - the matching string itself |
|
1780 | match - the matching string itself | |
1660 |
|
1781 | |||
1661 | """ |
|
1782 | ''' | |
1662 |
|
1783 | |||
1663 | def __init__(self, strings): |
|
1784 | def __init__(self, strings): | |
1664 |
|
1785 | |||
1665 |
|
|
1786 | '''This creates an instance of searcher_string. This argument 'strings' | |
1666 |
may be a list; a sequence of strings; or the EOF or TIMEOUT types. |
|
1787 | may be a list; a sequence of strings; or the EOF or TIMEOUT types. ''' | |
1667 |
|
1788 | |||
1668 | self.eof_index = -1 |
|
1789 | self.eof_index = -1 | |
1669 | self.timeout_index = -1 |
|
1790 | self.timeout_index = -1 | |
@@ -1679,21 +1800,23 b' class searcher_string (object):' | |||||
1679 |
|
1800 | |||
1680 | def __str__(self): |
|
1801 | def __str__(self): | |
1681 |
|
1802 | |||
1682 |
|
|
1803 | '''This returns a human-readable string that represents the state of | |
1683 |
the object. |
|
1804 | the object.''' | |
1684 |
|
1805 | |||
1685 |
ss = |
|
1806 | ss = [(ns[0], ' %d: "%s"' % ns) for ns in self._strings] | |
1686 | ss.append((-1,'searcher_string:')) |
|
1807 | ss.append((-1, 'searcher_string:')) | |
1687 | if self.eof_index >= 0: |
|
1808 | if self.eof_index >= 0: | |
1688 |
ss.append |
|
1809 | ss.append((self.eof_index, ' %d: EOF' % self.eof_index)) | |
1689 | if self.timeout_index >= 0: |
|
1810 | if self.timeout_index >= 0: | |
1690 |
ss.append |
|
1811 | ss.append((self.timeout_index, | |
|
1812 | ' %d: TIMEOUT' % self.timeout_index)) | |||
1691 | ss.sort() |
|
1813 | ss.sort() | |
1692 | return '\n'.join(a[1] for a in ss) |
|
1814 | ss = list(zip(*ss))[1] | |
|
1815 | return '\n'.join(ss) | |||
1693 |
|
1816 | |||
1694 | def search(self, buffer, freshlen, searchwindowsize=None): |
|
1817 | def search(self, buffer, freshlen, searchwindowsize=None): | |
1695 |
|
1818 | |||
1696 |
|
|
1819 | '''This searches 'buffer' for the first occurence of one of the search | |
1697 | strings. 'freshlen' must indicate the number of bytes at the end of |
|
1820 | strings. 'freshlen' must indicate the number of bytes at the end of | |
1698 | 'buffer' which have not been searched before. It helps to avoid |
|
1821 | 'buffer' which have not been searched before. It helps to avoid | |
1699 | searching the same, possibly big, buffer over and over again. |
|
1822 | searching the same, possibly big, buffer over and over again. | |
@@ -1701,10 +1824,9 b' class searcher_string (object):' | |||||
1701 | See class spawn for the 'searchwindowsize' argument. |
|
1824 | See class spawn for the 'searchwindowsize' argument. | |
1702 |
|
1825 | |||
1703 | If there is a match this returns the index of that string, and sets |
|
1826 | If there is a match this returns the index of that string, and sets | |
1704 |
'start', 'end' and 'match'. Otherwise, this returns -1. |
|
1827 | 'start', 'end' and 'match'. Otherwise, this returns -1. ''' | |
1705 |
|
1828 | |||
1706 |
|
|
1829 | first_match = None | |
1707 | first_match = absurd_match |
|
|||
1708 |
|
1830 | |||
1709 | # 'freshlen' helps a lot here. Further optimizations could |
|
1831 | # 'freshlen' helps a lot here. Further optimizations could | |
1710 | # possibly include: |
|
1832 | # possibly include: | |
@@ -1722,24 +1844,25 b' class searcher_string (object):' | |||||
1722 | if searchwindowsize is None: |
|
1844 | if searchwindowsize is None: | |
1723 | # the match, if any, can only be in the fresh data, |
|
1845 | # the match, if any, can only be in the fresh data, | |
1724 | # or at the very end of the old data |
|
1846 | # or at the very end of the old data | |
1725 | offset = -(freshlen+len(s)) |
|
1847 | offset = -(freshlen + len(s)) | |
1726 | else: |
|
1848 | else: | |
1727 | # better obey searchwindowsize |
|
1849 | # better obey searchwindowsize | |
1728 | offset = -searchwindowsize |
|
1850 | offset = -searchwindowsize | |
1729 | n = buffer.find(s, offset) |
|
1851 | n = buffer.find(s, offset) | |
1730 | if n >= 0 and n < first_match: |
|
1852 | if n >= 0 and (first_match is None or n < first_match): | |
1731 | first_match = n |
|
1853 | first_match = n | |
1732 | best_index, best_match = index, s |
|
1854 | best_index, best_match = index, s | |
1733 |
if first_match |
|
1855 | if first_match is None: | |
1734 | return -1 |
|
1856 | return -1 | |
1735 | self.match = best_match |
|
1857 | self.match = best_match | |
1736 | self.start = first_match |
|
1858 | self.start = first_match | |
1737 | self.end = self.start + len(self.match) |
|
1859 | self.end = self.start + len(self.match) | |
1738 | return best_index |
|
1860 | return best_index | |
1739 |
|
1861 | |||
1740 | class searcher_re (object): |
|
|||
1741 |
|
1862 | |||
1742 | """This is regular expression string search helper for the |
|
1863 | class searcher_re(object): | |
|
1864 | ||||
|
1865 | '''This is regular expression string search helper for the | |||
1743 | spawn.expect_any() method. This helper class is for powerful |
|
1866 | spawn.expect_any() method. This helper class is for powerful | |
1744 | pattern matching. For speed, see the helper class, searcher_string. |
|
1867 | pattern matching. For speed, see the helper class, searcher_string. | |
1745 |
|
1868 | |||
@@ -1755,18 +1878,18 b' class searcher_re (object):' | |||||
1755 | end - index into the buffer, first byte after match |
|
1878 | end - index into the buffer, first byte after match | |
1756 | match - the re.match object returned by a succesful re.search |
|
1879 | match - the re.match object returned by a succesful re.search | |
1757 |
|
1880 | |||
1758 | """ |
|
1881 | ''' | |
1759 |
|
1882 | |||
1760 | def __init__(self, patterns): |
|
1883 | def __init__(self, patterns): | |
1761 |
|
1884 | |||
1762 |
|
|
1885 | '''This creates an instance that searches for 'patterns' Where | |
1763 | 'patterns' may be a list or other sequence of compiled regular |
|
1886 | 'patterns' may be a list or other sequence of compiled regular | |
1764 |
expressions, or the EOF or TIMEOUT types. |
|
1887 | expressions, or the EOF or TIMEOUT types.''' | |
1765 |
|
1888 | |||
1766 | self.eof_index = -1 |
|
1889 | self.eof_index = -1 | |
1767 | self.timeout_index = -1 |
|
1890 | self.timeout_index = -1 | |
1768 | self._searches = [] |
|
1891 | self._searches = [] | |
1769 |
for n, s in |
|
1892 | for n, s in zip(list(range(len(patterns))), patterns): | |
1770 | if s is EOF: |
|
1893 | if s is EOF: | |
1771 | self.eof_index = n |
|
1894 | self.eof_index = n | |
1772 | continue |
|
1895 | continue | |
@@ -1777,83 +1900,93 b' class searcher_re (object):' | |||||
1777 |
|
1900 | |||
1778 | def __str__(self): |
|
1901 | def __str__(self): | |
1779 |
|
1902 | |||
1780 |
|
|
1903 | '''This returns a human-readable string that represents the state of | |
1781 |
the object. |
|
1904 | the object.''' | |
1782 |
|
1905 | |||
1783 |
ss = |
|
1906 | #ss = [(n, ' %d: re.compile("%s")' % | |
1784 | ss.append((-1,'searcher_re:')) |
|
1907 | # (n, repr(s.pattern))) for n, s in self._searches] | |
|
1908 | ss = list() | |||
|
1909 | for n, s in self._searches: | |||
|
1910 | try: | |||
|
1911 | ss.append((n, ' %d: re.compile("%s")' % (n, s.pattern))) | |||
|
1912 | except UnicodeEncodeError: | |||
|
1913 | # for test cases that display __str__ of searches, dont throw | |||
|
1914 | # another exception just because stdout is ascii-only, using | |||
|
1915 | # repr() | |||
|
1916 | ss.append((n, ' %d: re.compile(%r)' % (n, s.pattern))) | |||
|
1917 | ss.append((-1, 'searcher_re:')) | |||
1785 | if self.eof_index >= 0: |
|
1918 | if self.eof_index >= 0: | |
1786 |
ss.append |
|
1919 | ss.append((self.eof_index, ' %d: EOF' % self.eof_index)) | |
1787 | if self.timeout_index >= 0: |
|
1920 | if self.timeout_index >= 0: | |
1788 |
ss.append |
|
1921 | ss.append((self.timeout_index, ' %d: TIMEOUT' % | |
|
1922 | self.timeout_index)) | |||
1789 | ss.sort() |
|
1923 | ss.sort() | |
1790 | return '\n'.join(a[1] for a in ss) |
|
1924 | ss = list(zip(*ss))[1] | |
|
1925 | return '\n'.join(ss) | |||
1791 |
|
1926 | |||
1792 | def search(self, buffer, freshlen, searchwindowsize=None): |
|
1927 | def search(self, buffer, freshlen, searchwindowsize=None): | |
1793 |
|
1928 | |||
1794 |
|
|
1929 | '''This searches 'buffer' for the first occurence of one of the regular | |
1795 | expressions. 'freshlen' must indicate the number of bytes at the end of |
|
1930 | expressions. 'freshlen' must indicate the number of bytes at the end of | |
1796 | 'buffer' which have not been searched before. |
|
1931 | 'buffer' which have not been searched before. | |
1797 |
|
1932 | |||
1798 | See class spawn for the 'searchwindowsize' argument. |
|
1933 | See class spawn for the 'searchwindowsize' argument. | |
1799 |
|
1934 | |||
1800 | If there is a match this returns the index of that string, and sets |
|
1935 | If there is a match this returns the index of that string, and sets | |
1801 |
'start', 'end' and 'match'. Otherwise, returns -1. |
|
1936 | 'start', 'end' and 'match'. Otherwise, returns -1.''' | |
1802 |
|
1937 | |||
1803 |
|
|
1938 | first_match = None | |
1804 | first_match = absurd_match |
|
|||
1805 | # 'freshlen' doesn't help here -- we cannot predict the |
|
1939 | # 'freshlen' doesn't help here -- we cannot predict the | |
1806 | # length of a match, and the re module provides no help. |
|
1940 | # length of a match, and the re module provides no help. | |
1807 | if searchwindowsize is None: |
|
1941 | if searchwindowsize is None: | |
1808 | searchstart = 0 |
|
1942 | searchstart = 0 | |
1809 | else: |
|
1943 | else: | |
1810 | searchstart = max(0, len(buffer)-searchwindowsize) |
|
1944 | searchstart = max(0, len(buffer) - searchwindowsize) | |
1811 | for index, s in self._searches: |
|
1945 | for index, s in self._searches: | |
1812 | match = s.search(buffer, searchstart) |
|
1946 | match = s.search(buffer, searchstart) | |
1813 | if match is None: |
|
1947 | if match is None: | |
1814 | continue |
|
1948 | continue | |
1815 | n = match.start() |
|
1949 | n = match.start() | |
1816 | if n < first_match: |
|
1950 | if first_match is None or n < first_match: | |
1817 | first_match = n |
|
1951 | first_match = n | |
1818 | the_match = match |
|
1952 | the_match = match | |
1819 | best_index = index |
|
1953 | best_index = index | |
1820 |
if first_match |
|
1954 | if first_match is None: | |
1821 | return -1 |
|
1955 | return -1 | |
1822 | self.start = first_match |
|
1956 | self.start = first_match | |
1823 | self.match = the_match |
|
1957 | self.match = the_match | |
1824 | self.end = self.match.end() |
|
1958 | self.end = self.match.end() | |
1825 | return best_index |
|
1959 | return best_index | |
1826 |
|
1960 | |||
1827 | def which (filename): |
|
|||
1828 |
|
1961 | |||
1829 | """This takes a given filename; tries to find it in the environment path; |
|
1962 | def which(filename): | |
|
1963 | ||||
|
1964 | '''This takes a given filename; tries to find it in the environment path; | |||
1830 | then checks if it is executable. This returns the full path to the filename |
|
1965 | then checks if it is executable. This returns the full path to the filename | |
1831 |
if found and executable. Otherwise this returns None. |
|
1966 | if found and executable. Otherwise this returns None.''' | |
1832 |
|
1967 | |||
1833 |
# Special case where filename |
|
1968 | # Special case where filename contains an explicit path. | |
1834 | if os.path.dirname(filename) != '': |
|
1969 | if os.path.dirname(filename) != '': | |
1835 |
if os.access |
|
1970 | if os.access(filename, os.X_OK): | |
1836 | return filename |
|
1971 | return filename | |
1837 |
|
||||
1838 | if 'PATH' not in os.environ or os.environ['PATH'] == '': |
|
1972 | if 'PATH' not in os.environ or os.environ['PATH'] == '': | |
1839 | p = os.defpath |
|
1973 | p = os.defpath | |
1840 | else: |
|
1974 | else: | |
1841 | p = os.environ['PATH'] |
|
1975 | p = os.environ['PATH'] | |
1842 |
|
||||
1843 | pathlist = p.split(os.pathsep) |
|
1976 | pathlist = p.split(os.pathsep) | |
1844 |
|
||||
1845 | for path in pathlist: |
|
1977 | for path in pathlist: | |
1846 | f = os.path.join(path, filename) |
|
1978 | ff = os.path.join(path, filename) | |
1847 | if os.access(f, os.X_OK): |
|
1979 | if os.access(ff, os.X_OK): | |
1848 | return f |
|
1980 | return ff | |
1849 | return None |
|
1981 | return None | |
1850 |
|
1982 | |||
|
1983 | ||||
1851 | def split_command_line(command_line): |
|
1984 | def split_command_line(command_line): | |
1852 |
|
1985 | |||
1853 |
|
|
1986 | '''This splits a command line into a list of arguments. It splits arguments | |
1854 | on spaces, but handles embedded quotes, doublequotes, and escaped |
|
1987 | on spaces, but handles embedded quotes, doublequotes, and escaped | |
1855 | characters. It's impossible to do this with a regular expression, so I |
|
1988 | characters. It's impossible to do this with a regular expression, so I | |
1856 |
wrote a little state machine to parse the command line. |
|
1989 | wrote a little state machine to parse the command line. ''' | |
1857 |
|
1990 | |||
1858 | arg_list = [] |
|
1991 | arg_list = [] | |
1859 | arg = '' |
|
1992 | arg = '' | |
@@ -1863,21 +1996,26 b' def split_command_line(command_line):' | |||||
1863 | state_esc = 1 |
|
1996 | state_esc = 1 | |
1864 | state_singlequote = 2 |
|
1997 | state_singlequote = 2 | |
1865 | state_doublequote = 3 |
|
1998 | state_doublequote = 3 | |
1866 |
|
|
1999 | # The state when consuming whitespace between commands. | |
|
2000 | state_whitespace = 4 | |||
1867 | state = state_basic |
|
2001 | state = state_basic | |
1868 |
|
2002 | |||
1869 | for c in command_line: |
|
2003 | for c in command_line: | |
1870 | if state == state_basic or state == state_whitespace: |
|
2004 | if state == state_basic or state == state_whitespace: | |
1871 |
if c == '\\': |
|
2005 | if c == '\\': | |
|
2006 | # Escape the next character | |||
1872 | state = state_esc |
|
2007 | state = state_esc | |
1873 |
elif c == r"'": |
|
2008 | elif c == r"'": | |
|
2009 | # Handle single quote | |||
1874 | state = state_singlequote |
|
2010 | state = state_singlequote | |
1875 |
elif c == r'"': |
|
2011 | elif c == r'"': | |
|
2012 | # Handle double quote | |||
1876 | state = state_doublequote |
|
2013 | state = state_doublequote | |
1877 | elif c.isspace(): |
|
2014 | elif c.isspace(): | |
1878 | # Add arg to arg_list if we aren't in the middle of whitespace. |
|
2015 | # Add arg to arg_list if we aren't in the middle of whitespace. | |
1879 | if state == state_whitespace: |
|
2016 | if state == state_whitespace: | |
1880 |
|
|
2017 | # Do nothing. | |
|
2018 | None | |||
1881 | else: |
|
2019 | else: | |
1882 | arg_list.append(arg) |
|
2020 | arg_list.append(arg) | |
1883 | arg = '' |
|
2021 | arg = '' |
General Comments 0
You need to be logged in to leave comments.
Login now