or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

alternative-spawning.mdindex.mdpattern-matching.mdprocess-control.mdrepl-automation.mdssh-operations.mdutilities.md

alternative-spawning.mddocs/

0

# Alternative Process Control

1

2

Alternative spawn implementations for different communication mechanisms. These classes provide expect-like functionality for scenarios where the standard PTY-based spawn is not suitable or available.

3

4

## Capabilities

5

6

### Subprocess-based Spawning

7

8

Process control using subprocess.Popen instead of pseudo-terminals, useful for Windows compatibility and certain Unix scenarios.

9

10

```python { .api }

11

class PopenSpawn(SpawnBase):

12

"""

13

Spawn class using subprocess.Popen for process communication.

14

15

Uses pipes instead of pseudo-terminals, making it compatible with Windows

16

and useful for scenarios where PTY behavior is not desired.

17

"""

18

19

def __init__(self, cmd, timeout=30, maxread=2000, searchwindowsize=None,

20

logfile=None, cwd=None, env=None, encoding=None,

21

codec_errors='strict', preexec_fn=None):

22

"""

23

Initialize PopenSpawn instance.

24

25

Parameters:

26

- cmd (str or list): Command to execute

27

- timeout (int): Default timeout for operations

28

- maxread (int): Maximum bytes to read at once

29

- searchwindowsize (int): Search window size for pattern matching

30

- logfile (file-like): File object for logging

31

- cwd (str): Working directory for child process

32

- env (dict): Environment variables for child process

33

- encoding (str): Text encoding for I/O operations

34

- codec_errors (str): How to handle encoding errors

35

- preexec_fn (callable): Function to call before exec (Unix only)

36

"""

37

```

38

39

### File Descriptor Control

40

41

Control existing file descriptors such as sockets, pipes, or other file-like objects with expect functionality.

42

43

```python { .api }

44

class fdspawn(SpawnBase):

45

"""

46

Spawn-like interface for existing file descriptors.

47

48

Allows expect functionality with sockets, named pipes (FIFOs),

49

or any existing file descriptor.

50

51

Note: On Windows, socket.fileno() doesn't provide a readable

52

file descriptor. Use SocketSpawn for cross-platform socket support.

53

"""

54

55

def __init__(self, fd, args=None, timeout=30, maxread=2000,

56

searchwindowsize=None, logfile=None, encoding=None,

57

codec_errors='strict', use_poll=False):

58

"""

59

Initialize fdspawn with existing file descriptor.

60

61

Parameters:

62

- fd (int): Existing file descriptor

63

- args (list): Arguments for compatibility (not used)

64

- timeout (int): Default timeout for operations

65

- maxread (int): Maximum bytes to read at once

66

- searchwindowsize (int): Search window size

67

- logfile (file-like): File object for logging

68

- encoding (str): Text encoding for I/O operations

69

- codec_errors (str): How to handle encoding errors

70

- use_poll (bool): Use poll() instead of select() for I/O

71

"""

72

73

def isalive(self):

74

"""

75

Check if file descriptor is still valid.

76

77

Returns:

78

bool: True if file descriptor is open and valid

79

"""

80

81

def close(self):

82

"""Close the file descriptor."""

83

84

def fileno(self):

85

"""

86

Get the file descriptor number.

87

88

Returns:

89

int: File descriptor number

90

"""

91

```

92

93

### Socket Communication

94

95

Cross-platform socket communication with expect functionality, particularly useful for network automation.

96

97

```python { .api }

98

class SocketSpawn(SpawnBase):

99

"""

100

Spawn-like interface for socket communication.

101

102

Provides expect functionality for socket connections,

103

useful for network protocol automation and testing.

104

"""

105

106

def __init__(self, socket, args=None, timeout=30, maxread=2000,

107

searchwindowsize=None, logfile=None, encoding=None,

108

codec_errors='strict'):

109

"""

110

Initialize SocketSpawn with existing socket.

111

112

Parameters:

113

- socket (socket.socket): Connected socket object

114

- args (list): Arguments for compatibility (not used)

115

- timeout (int): Default timeout for operations

116

- maxread (int): Maximum bytes to read at once

117

- searchwindowsize (int): Search window size

118

- logfile (file-like): File object for logging

119

- encoding (str): Text encoding for I/O operations

120

- codec_errors (str): How to handle encoding errors

121

"""

122

123

def close(self):

124

"""Close the socket connection."""

125

126

def isalive(self):

127

"""

128

Check if socket connection is still active.

129

130

Returns:

131

bool: True if socket is connected

132

"""

133

134

def fileno(self):

135

"""

136

Get the socket file descriptor.

137

138

Returns:

139

int: Socket file descriptor

140

"""

141

```

142

143

## Usage Examples

144

145

### PopenSpawn for Cross-Platform Compatibility

146

147

```python

148

from pexpect.popen_spawn import PopenSpawn

149

import sys

150

151

# PopenSpawn works on both Unix and Windows

152

if sys.platform == 'win32':

153

# Windows command

154

child = PopenSpawn('cmd.exe')

155

child.expect('>')

156

child.sendline('dir')

157

child.expect('>')

158

print(child.before.decode())

159

else:

160

# Unix command

161

child = PopenSpawn('bash')

162

child.expect('$ ')

163

child.sendline('ls -la')

164

child.expect('$ ')

165

print(child.before.decode())

166

167

child.close()

168

```

169

170

### PopenSpawn with Complex Commands

171

172

```python

173

from pexpect.popen_spawn import PopenSpawn

174

175

# Execute complex command with arguments

176

child = PopenSpawn(['python', '-c', 'print("Hello"); input("Enter: ")'])

177

178

# Wait for the input prompt

179

child.expect('Enter: ')

180

181

# Send input

182

child.sendline('World')

183

184

# Read the output

185

child.expect(pexpect.EOF)

186

output = child.before.decode()

187

print(f"Output: {output}")

188

189

child.close()

190

```

191

192

### File Descriptor Control with Named Pipes

193

194

```python

195

from pexpect.fdpexpect import fdspawn

196

import os

197

198

# Create a named pipe (FIFO)

199

pipe_path = '/tmp/test_pipe'

200

if not os.path.exists(pipe_path):

201

os.mkfifo(pipe_path)

202

203

# Open the pipe for reading/writing

204

fd = os.open(pipe_path, os.O_RDWR)

205

206

# Create fdspawn instance

207

child = fdspawn(fd)

208

209

# In another process/thread, write to the pipe

210

# For this example, we'll simulate it

211

os.write(fd, b'Hello from pipe\n')

212

213

# Use expect functionality

214

child.expect('Hello')

215

print(f"Received: {child.after.decode()}")

216

217

child.close()

218

os.unlink(pipe_path) # Clean up

219

```

220

221

### Socket Communication Example

222

223

```python

224

from pexpect.socket_pexpect import SocketSpawn

225

import socket

226

227

# Create and connect socket

228

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

229

sock.connect(('httpbin.org', 80))

230

231

# Create SocketSpawn instance

232

child = SocketSpawn(sock)

233

234

# Send HTTP request

235

child.send('GET /get HTTP/1.1\r\n')

236

child.send('Host: httpbin.org\r\n')

237

child.send('Connection: close\r\n')

238

child.send('\r\n')

239

240

# Wait for HTTP response

241

child.expect('HTTP/')

242

print("Got HTTP response header")

243

244

# Read response body

245

child.expect('200 OK')

246

child.expect('\r\n\r\n') # End of headers

247

248

# Read JSON response

249

child.expect(pexpect.EOF)

250

response_body = child.before.decode()

251

print(f"Response: {response_body}")

252

253

child.close()

254

```

255

256

### FTP Automation with Socket

257

258

```python

259

from pexpect.socket_pexpect import SocketSpawn

260

import socket

261

262

# Connect to FTP server

263

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

264

sock.connect(('ftp.example.com', 21))

265

266

child = SocketSpawn(sock)

267

268

# Wait for FTP welcome message

269

child.expect('220')

270

print("Connected to FTP server")

271

272

# Send username

273

child.sendline('USER anonymous')

274

child.expect('331') # User name okay, need password

275

276

# Send password

277

child.sendline('PASS guest@example.com')

278

child.expect('230') # User logged in

279

print("Logged in successfully")

280

281

# List directory

282

child.sendline('LIST')

283

child.expect('150') # File status okay, about to open data connection

284

child.expect('226') # Closing data connection

285

directory_listing = child.before.decode()

286

print(f"Directory listing:\n{directory_listing}")

287

288

# Quit

289

child.sendline('QUIT')

290

child.expect('221') # Service closing control connection

291

print("Disconnected from FTP server")

292

293

child.close()

294

```

295

296

### Telnet Automation with Socket

297

298

```python

299

from pexpect.socket_pexpect import SocketSpawn

300

import socket

301

302

# Connect to telnet server

303

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

304

sock.connect(('towel.blinkenlights.nl', 23)) # Star Wars ASCII movie

305

306

child = SocketSpawn(sock, encoding='utf-8')

307

308

try:

309

# Just watch the ASCII movie for a bit

310

for i in range(10): # Watch for 10 iterations

311

child.expect('\x1b[H') # ANSI clear screen sequence

312

frame = child.before

313

print(f"Frame {i+1}")

314

# Could process or display the frame here

315

316

except KeyboardInterrupt:

317

print("Stopping...")

318

319

child.close()

320

```

321

322

### Process Pipeline with fdspawn

323

324

```python

325

from pexpect.fdpexpect import fdspawn

326

import subprocess

327

import os

328

329

# Create a process pipeline

330

p1 = subprocess.Popen(['ls', '-la'], stdout=subprocess.PIPE)

331

p2 = subprocess.Popen(['grep', 'pexpect'], stdin=p1.stdout, stdout=subprocess.PIPE)

332

333

# Use fdspawn to interact with the pipeline output

334

child = fdspawn(p2.stdout.fileno())

335

336

try:

337

# Read output with expect

338

child.expect(pexpect.EOF)

339

result = child.before.decode()

340

print(f"Filtered output:\n{result}")

341

342

except pexpect.EOF:

343

# Expected when process completes

344

pass

345

346

# Clean up

347

p1.stdout.close()

348

p2.stdout.close()

349

p1.wait()

350

p2.wait()

351

child.close()

352

```

353

354

### Windows Command Automation

355

356

```python

357

from pexpect.popen_spawn import PopenSpawn

358

import sys

359

360

if sys.platform == 'win32':

361

# Windows PowerShell automation

362

child = PopenSpawn(['powershell.exe', '-Command', '-'])

363

364

# Wait for PowerShell prompt

365

child.expect('PS ')

366

367

# Execute PowerShell commands

368

child.sendline('Get-Date')

369

child.expect('PS ')

370

date_output = child.before.decode()

371

print(f"Current date: {date_output}")

372

373

child.sendline('Get-Process | Select-Object -First 5')

374

child.expect('PS ')

375

process_output = child.before.decode()

376

print(f"Top processes:\n{process_output}")

377

378

# Exit PowerShell

379

child.sendline('exit')

380

child.close()

381

382

else:

383

print("This example is for Windows only")

384

```

385

386

## Key Differences from Standard Spawn

387

388

### PopenSpawn vs spawn

389

390

- **PopenSpawn**: Uses subprocess.Popen, no PTY, works on Windows

391

- **spawn**: Uses pseudo-terminal, Unix-only, full terminal emulation

392

393

### fdspawn vs spawn

394

395

- **fdspawn**: Works with existing file descriptors, no process management

396

- **spawn**: Creates and manages child processes with PTY

397

398

### SocketSpawn vs spawn

399

400

- **SocketSpawn**: Network communication, no process involved

401

- **spawn**: Local process communication with PTY

402

403

## Choosing the Right Spawn Class

404

405

- **spawn**: Standard choice for Unix process automation

406

- **PopenSpawn**: Cross-platform compatibility, Windows support

407

- **fdspawn**: Existing file descriptors, pipes, custom I/O

408

- **SocketSpawn**: Network protocols, socket communication

409

- **pxssh**: SSH connections (uses spawn internally)