0
# Pattern Matching and Expect Operations
1
2
Powerful pattern matching system for waiting for expected output from child processes. The expect system is the core of pexpect's automation capabilities, allowing scripts to wait for specific patterns before proceeding.
3
4
## Capabilities
5
6
### Core Expect Methods
7
8
The primary methods for pattern matching and synchronization with child processes.
9
10
```python { .api }
11
def expect(self, pattern, timeout=-1, searchwindowsize=-1, async_=False, **kw):
12
"""
13
Wait for pattern in child output.
14
15
Parameters:
16
- pattern (str, bytes, regex, list): Pattern(s) to match
17
- timeout (int): Timeout in seconds (-1 for default)
18
- searchwindowsize (int): Buffer size for pattern search
19
- async_ (bool): Return asyncio Future on Python 3.4+ (default: False)
20
- **kw: Additional keyword arguments
21
22
Returns:
23
int or asyncio.Future: Index of matched pattern (0 for single pattern)
24
25
Raises:
26
- TIMEOUT: If pattern not found within timeout
27
- EOF: If child process terminates before pattern found
28
"""
29
30
def expect_list(self, pattern_list, timeout=-1, searchwindowsize=-1, async_=False, **kw):
31
"""
32
Wait for any pattern from a list of patterns.
33
34
Parameters:
35
- pattern_list (list): List of patterns to match
36
- timeout (int): Timeout in seconds
37
- searchwindowsize (int): Buffer size for pattern search
38
- async_ (bool): Return asyncio Future on Python 3.4+ (default: False)
39
- **kw: Additional keyword arguments
40
41
Returns:
42
int or asyncio.Future: Index of matched pattern in the list
43
"""
44
45
def expect_exact(self, pattern_list, timeout=-1, searchwindowsize=-1, async_=False, **kw):
46
"""
47
Wait for exact string matches (no regex interpretation).
48
49
Parameters:
50
- pattern_list (list): List of exact strings to match
51
- timeout (int): Timeout in seconds
52
- searchwindowsize (int): Buffer size for pattern search
53
- async_ (bool): Return asyncio Future on Python 3.4+ (default: False)
54
- **kw: Additional keyword arguments
55
56
Returns:
57
int or asyncio.Future: Index of matched pattern in the list
58
"""
59
60
def expect_loop(self, searcher, timeout=-1):
61
"""
62
Core expect loop that handles the actual pattern matching.
63
64
Parameters:
65
- searcher (searcher_string or searcher_re): Pattern searcher object
66
- timeout (int): Timeout in seconds
67
68
Returns:
69
int: Index of matched pattern
70
"""
71
72
def compile_pattern_list(self, patterns):
73
"""
74
Compile list of patterns into searcher objects.
75
76
Parameters:
77
- patterns (list): List of patterns (strings, regex, EOF, TIMEOUT)
78
79
Returns:
80
searcher_string or searcher_re: Compiled pattern searcher
81
"""
82
```
83
84
### Pattern Searcher Classes
85
86
Classes that handle different types of pattern matching internally.
87
88
```python { .api }
89
class searcher_string:
90
"""
91
Fast string searcher for exact string matching.
92
"""
93
def __init__(self, strings, index):
94
"""
95
Parameters:
96
- strings (list): List of strings to search for
97
- index (int): Starting index for pattern numbering
98
"""
99
100
eof_index: int # Index returned when EOF encountered
101
timeout_index: int # Index returned when timeout occurs
102
103
class searcher_re:
104
"""
105
Regular expression searcher for pattern matching.
106
"""
107
def __init__(self, patterns, index):
108
"""
109
Parameters:
110
- patterns (list): List of regex patterns (compiled or string)
111
- index (int): Starting index for pattern numbering
112
"""
113
114
eof_index: int # Index returned when EOF encountered
115
timeout_index: int # Index returned when timeout occurs
116
```
117
118
### Pattern Matching Coordinator
119
120
Internal class that manages the expect operations.
121
122
```python { .api }
123
class Expecter:
124
"""
125
Coordinates pattern searching operations.
126
"""
127
def __init__(self, spawn, searcher, searchwindowsize=-1):
128
"""
129
Parameters:
130
- spawn: The spawn object being monitored
131
- searcher: Pattern searcher object
132
- searchwindowsize (int): Size of search window
133
"""
134
135
def do_search(self, window, freshlen):
136
"""
137
Perform pattern search on data window.
138
139
Parameters:
140
- window (bytes): Data buffer to search
141
- freshlen (int): Length of new data in buffer
142
143
Returns:
144
int: Match index or -1 if no match
145
"""
146
147
def existing_data(self):
148
"""Handle search on existing buffered data."""
149
150
def new_data(self, data):
151
"""Handle search on newly received data."""
152
```
153
154
## Pattern Types and Syntax
155
156
### String Patterns
157
158
```python
159
# Simple string matching
160
child.expect('Password:')
161
child.expect(b'binary_string')
162
163
# Multiple string options
164
index = child.expect(['choice1', 'choice2', 'choice3'])
165
if index == 0:
166
print("Got choice1")
167
elif index == 1:
168
print("Got choice2")
169
```
170
171
### Regular Expression Patterns
172
173
```python
174
import re
175
176
# Regex patterns
177
child.expect(r'\$ ') # Shell prompt
178
child.expect(r'[Pp]assword:') # Case insensitive password prompt
179
child.expect(re.compile(r'\d+\.\d+\.\d+\.\d+')) # IP address
180
181
# Compiled regex patterns
182
pattern = re.compile(r'([A-Za-z]+): (\d+)')
183
child.expect(pattern)
184
# Access captured groups via child.match.groups()
185
```
186
187
### Special Patterns
188
189
```python
190
# Built-in special patterns
191
child.expect(pexpect.EOF) # Wait for process to end
192
child.expect(pexpect.TIMEOUT) # Handle timeout explicitly
193
194
# Mixed pattern lists
195
patterns = [
196
'success', # String pattern
197
re.compile(r'error: (.+)'), # Regex pattern
198
pexpect.TIMEOUT, # Timeout handler
199
pexpect.EOF # EOF handler
200
]
201
index = child.expect(patterns, timeout=30)
202
```
203
204
## Advanced Pattern Matching
205
206
### Using Search Window Size
207
208
```python
209
# Limit search buffer size for performance
210
child.expect('pattern', searchwindowsize=1000)
211
212
# Useful for streaming data or very long output
213
child = pexpect.spawn('tail -f /var/log/messages')
214
child.expect('ERROR', searchwindowsize=500)
215
```
216
217
### Timeout Handling
218
219
```python
220
import pexpect
221
222
child = pexpect.spawn('slow_command')
223
224
try:
225
index = child.expect(['Success', 'Error'], timeout=10)
226
if index == 0:
227
print("Command succeeded")
228
else:
229
print("Command failed")
230
except pexpect.TIMEOUT:
231
print("Command timed out")
232
# Optionally kill the process
233
child.kill(signal.SIGTERM)
234
except pexpect.EOF:
235
print("Process ended unexpectedly")
236
```
237
238
### Accessing Match Results
239
240
```python
241
import pexpect
242
import re
243
244
child = pexpect.spawn('some_command')
245
246
# String matching - access matched text
247
child.expect('Found: ')
248
print(f"Before match: {child.before}")
249
print(f"Matched text: {child.after}")
250
251
# Regex matching - access capture groups
252
pattern = re.compile(r'Result: (\d+) items processed')
253
child.expect(pattern)
254
print(f"Items processed: {child.match.group(1)}")
255
256
# Multiple patterns - check which matched
257
patterns = ['success', 'warning', 'error']
258
index = child.expect(patterns)
259
print(f"Matched pattern #{index}: {patterns[index]}")
260
```
261
262
## Usage Examples
263
264
### Basic Pattern Matching
265
266
```python
267
import pexpect
268
269
# Simple login automation
270
child = pexpect.spawn('ssh user@server')
271
child.expect('Password:')
272
child.sendline('mypassword')
273
child.expect('$ ')
274
print("Successfully logged in")
275
```
276
277
### Handling Multiple Scenarios
278
279
```python
280
import pexpect
281
282
child = pexpect.spawn('ssh user@server')
283
284
# Handle multiple possible responses
285
index = child.expect([
286
'Password:', # Index 0: Password prompt
287
'Are you sure', # Index 1: Host key verification
288
'Permission denied', # Index 2: Already failed
289
pexpect.TIMEOUT # Index 3: Timeout
290
])
291
292
if index == 0:
293
child.sendline('mypassword')
294
child.expect('$ ')
295
elif index == 1:
296
child.sendline('yes')
297
child.expect('Password:')
298
child.sendline('mypassword')
299
child.expect('$ ')
300
elif index == 2:
301
print("Login failed - permission denied")
302
child.close()
303
elif index == 3:
304
print("Connection timed out")
305
child.close()
306
```
307
308
### Complex Regex Matching
309
310
```python
311
import pexpect
312
import re
313
314
child = pexpect.spawn('ping google.com')
315
316
# Match ping statistics with regex
317
pattern = re.compile(r'(\d+) packets transmitted, (\d+) received')
318
child.expect(pattern, timeout=60)
319
320
transmitted = child.match.group(1)
321
received = child.match.group(2)
322
print(f"Transmitted: {transmitted}, Received: {received}")
323
```
324
325
### Continuous Monitoring
326
327
```python
328
import pexpect
329
330
# Monitor log file for errors
331
child = pexpect.spawn('tail -f /var/log/application.log')
332
333
while True:
334
try:
335
index = child.expect([
336
re.compile(r'ERROR: (.+)'),
337
re.compile(r'WARNING: (.+)'),
338
pexpect.TIMEOUT
339
], timeout=5)
340
341
if index == 0: # Error found
342
error_msg = child.match.group(1)
343
print(f"Error detected: {error_msg}")
344
elif index == 1: # Warning found
345
warning_msg = child.match.group(1)
346
print(f"Warning: {warning_msg}")
347
# timeout index (2) - continue monitoring
348
349
except KeyboardInterrupt:
350
break
351
352
child.close()
353
```
354
355
### Exact String Matching
356
357
```python
358
import pexpect
359
360
child = pexpect.spawn('interactive_program')
361
362
# Use expect_exact for literal string matching (no regex interpretation)
363
# Useful when patterns contain regex special characters
364
child.expect_exact(['[INFO]', '[ERROR]', '[DEBUG]'])
365
366
# This avoids issues with square brackets being interpreted as regex character classes
367
```