or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

command-execution.mdcontrib.mderror-handling.mdindex.mdio-handling.mdprocess-management.mdutilities.md

process-management.mddocs/

0

# Process Management

1

2

Advanced process control including background execution, process monitoring, signal handling, and process lifecycle management. Provides comprehensive control over long-running commands and process interactions.

3

4

## Capabilities

5

6

### Process Lifecycle Control

7

8

Manage the lifecycle of running processes with methods to wait, terminate, and kill processes.

9

10

```python { .api }

11

class RunningCommand:

12

def wait(self):

13

"""

14

Wait for the process to complete.

15

16

Returns:

17

None

18

19

Raises:

20

ErrorReturnCode: If process exits with non-zero status

21

"""

22

23

def kill(self):

24

"""

25

Forcefully kill the process with SIGKILL.

26

27

Returns:

28

None

29

"""

30

31

def terminate(self):

32

"""

33

Gracefully terminate the process with SIGTERM.

34

35

Returns:

36

None

37

"""

38

```

39

40

Usage examples:

41

42

```python

43

import sh

44

import time

45

46

# Start a long-running process

47

proc = sh.sleep(30, _bg=True)

48

49

# Check if we need to cancel it

50

time.sleep(5)

51

if some_condition:

52

proc.terminate() # Try graceful termination first

53

time.sleep(2)

54

if proc.is_alive():

55

proc.kill() # Force kill if still running

56

57

# Wait for normal completion

58

try:

59

proc.wait()

60

print("Process completed normally")

61

except sh.ErrorReturnCode as e:

62

print(f"Process failed: {e}")

63

```

64

65

### Process Status Monitoring

66

67

Monitor process status and retrieve process information.

68

69

```python { .api }

70

class RunningCommand:

71

def is_alive(self) -> bool:

72

"""

73

Check if the process is still running.

74

75

Returns:

76

bool: True if process is running, False otherwise

77

"""

78

79

@property

80

def pid(self) -> int:

81

"""Process ID of the running command."""

82

83

@property

84

def exit_code(self) -> int:

85

"""Exit code of the process (None if still running)."""

86

```

87

88

Usage examples:

89

90

```python

91

import sh

92

import time

93

94

# Monitor multiple background processes

95

processes = [

96

sh.ping("-c", "10", "google.com", _bg=True),

97

sh.wget("http://example.com/large-file.zip", _bg=True),

98

sh.rsync("-av", "/source/", "/dest/", _bg=True)

99

]

100

101

# Monitor all processes

102

while any(proc.is_alive() for proc in processes):

103

for i, proc in enumerate(processes):

104

if proc.is_alive():

105

print(f"Process {i} (PID {proc.pid}) still running...")

106

else:

107

print(f"Process {i} completed with exit code {proc.exit_code}")

108

time.sleep(5)

109

110

print("All processes completed")

111

```

112

113

### Signal Handling

114

115

Send signals to running processes for advanced process control.

116

117

```python { .api }

118

class RunningCommand:

119

def signal(self, sig):

120

"""

121

Send a signal to the process.

122

123

Parameters:

124

- sig: int or signal constant (e.g., signal.SIGUSR1)

125

126

Returns:

127

None

128

"""

129

```

130

131

Usage examples:

132

133

```python

134

import sh

135

import signal

136

import time

137

138

# Start a process that handles signals

139

proc = sh.tail("-f", "/var/log/system.log", _bg=True)

140

141

# Let it run for a while

142

time.sleep(10)

143

144

# Send a custom signal (if the process handles it)

145

proc.signal(signal.SIGUSR1)

146

147

# Send SIGTERM for graceful shutdown

148

proc.signal(signal.SIGTERM)

149

150

# Wait a bit, then force kill if needed

151

time.sleep(2)

152

if proc.is_alive():

153

proc.signal(signal.SIGKILL)

154

```

155

156

### Process Groups and Session Management

157

158

Manage process groups and sessions for complex process hierarchies.

159

160

```python { .api }

161

def __call__(self, *args, _new_session=False, **kwargs):

162

"""

163

Execute command with process group control.

164

165

Parameters:

166

- _new_session: bool = True to start in new session

167

168

Returns:

169

RunningCommand: Process object

170

"""

171

```

172

173

Usage examples:

174

175

```python

176

import sh

177

178

# Start process in new session (detached from parent)

179

daemon_proc = sh.python("daemon.py", _bg=True, _new_session=True)

180

181

# This process will continue even if parent script exits

182

print(f"Daemon started with PID {daemon_proc.pid}")

183

184

# The daemon is now independent of this script's lifecycle

185

```

186

187

### Timeout Management

188

189

Handle process timeouts and long-running command management.

190

191

```python { .api }

192

def __call__(self, *args, _timeout=None, **kwargs):

193

"""

194

Execute command with timeout.

195

196

Parameters:

197

- _timeout: int/float = seconds to wait before killing process

198

199

Returns:

200

str: Command output

201

202

Raises:

203

TimeoutException: If command exceeds timeout

204

"""

205

```

206

207

Usage examples:

208

209

```python

210

import sh

211

212

# Set timeout for potentially hanging commands

213

try:

214

# Network command that might hang

215

result = sh.curl("http://slow-server.com", _timeout=30)

216

print("Download completed:", result)

217

except sh.TimeoutException:

218

print("Download timed out after 30 seconds")

219

220

# Background process with timeout monitoring

221

proc = sh.sleep(60, _bg=True)

222

223

start_time = time.time()

224

timeout = 10

225

226

while proc.is_alive():

227

if time.time() - start_time > timeout:

228

print("Manually timing out process")

229

proc.terminate()

230

break

231

time.sleep(1)

232

```

233

234

### Process Resource Management

235

236

Monitor and control process resources.

237

238

```python { .api }

239

class RunningCommand:

240

@property

241

def process(self):

242

"""Access to underlying subprocess.Popen object."""

243

```

244

245

Usage examples:

246

247

```python

248

import sh

249

import psutil # External library for extended process info

250

251

# Get detailed process information

252

proc = sh.find("/", "-name", "*.log", _bg=True)

253

254

# Access underlying process for advanced control

255

popen = proc.process

256

print(f"Process memory usage: {popen.memory_info()}")

257

258

# Use with psutil for extended monitoring

259

if hasattr(psutil, 'Process'):

260

ps_proc = psutil.Process(proc.pid)

261

print(f"CPU usage: {ps_proc.cpu_percent()}")

262

print(f"Memory usage: {ps_proc.memory_info()}")

263

```

264

265

### Batch Process Management

266

267

Manage multiple related processes as a group.

268

269

```python

270

import sh

271

import time

272

273

class ProcessManager:

274

def __init__(self):

275

self.processes = []

276

277

def start(self, command, *args, **kwargs):

278

"""Start a process and add to management."""

279

proc = command(*args, _bg=True, **kwargs)

280

self.processes.append(proc)

281

return proc

282

283

def wait_all(self):

284

"""Wait for all processes to complete."""

285

for proc in self.processes:

286

proc.wait()

287

288

def kill_all(self):

289

"""Kill all running processes."""

290

for proc in self.processes:

291

if proc.is_alive():

292

proc.kill()

293

294

def status(self):

295

"""Get status of all processes."""

296

running = sum(1 for p in self.processes if p.is_alive())

297

total = len(self.processes)

298

return f"{running}/{total} processes running"

299

300

# Usage

301

manager = ProcessManager()

302

303

# Start multiple related processes

304

manager.start(sh.rsync, "-av", "/data1/", "/backup/")

305

manager.start(sh.rsync, "-av", "/data2/", "/backup/")

306

manager.start(sh.rsync, "-av", "/data3/", "/backup/")

307

308

# Monitor progress

309

while any(p.is_alive() for p in manager.processes):

310

print(manager.status())

311

time.sleep(5)

312

313

print("All backups completed")

314

```