0
# Process Management
1
2
Commands for executing external processes, managing directory stacks, and controlling the shell environment and program flow.
3
4
## Capabilities
5
6
### exec - Execute External Commands
7
8
Executes external shell commands synchronously or asynchronously with comprehensive options for process control.
9
10
```javascript { .api }
11
/**
12
* Execute external shell commands
13
* @param command - Command string to execute
14
* @param options - Execution options
15
* @param callback - Optional callback for async execution
16
* @returns ShellString with code, stdout, and stderr properties
17
*/
18
function exec(command: string, options?: ExecOptions, callback?: ExecCallback): ShellString;
19
function exec(command: string, callback: ExecCallback): ShellString;
20
21
interface ExecOptions {
22
/** Character encoding for output (default: 'utf8') */
23
encoding?: string;
24
/** Suppress command output (default: false) */
25
silent?: boolean;
26
/** Execute asynchronously when callback provided (default: false) */
27
async?: boolean;
28
/** Throw error on non-zero exit code (default: config.fatal) */
29
fatal?: boolean;
30
/** Working directory for command execution */
31
cwd?: string;
32
/** Environment variables for the process */
33
env?: NodeJS.ProcessEnv;
34
/** Maximum buffer size for stdout/stderr (default: 20MB) */
35
maxBuffer?: number;
36
}
37
38
type ExecCallback = (code: number, stdout: string, stderr: string) => void;
39
```
40
41
**Usage Examples:**
42
43
```javascript
44
// Simple synchronous execution
45
const result = shell.exec('ls -la');
46
console.log('Exit code:', result.code);
47
console.log('Output:', result.stdout);
48
49
// Check exit code for errors
50
if (shell.exec('npm test').code !== 0) {
51
shell.echo('Tests failed');
52
shell.exit(1);
53
}
54
55
// Asynchronous execution with callback
56
shell.exec('long-running-command', function(code, stdout, stderr) {
57
console.log('Exit code:', code);
58
console.log('Output:', stdout);
59
});
60
61
// Execution with options
62
const gitResult = shell.exec('git status', {
63
silent: true,
64
cwd: '/path/to/repo',
65
env: { ...process.env, GIT_AUTHOR_NAME: 'Bot' }
66
});
67
68
// Capture output
69
const version = shell.exec('node --version', { silent: true }).stdout.trim();
70
71
// Error handling with fatal mode
72
shell.exec('risky-command', { fatal: true }); // Throws on non-zero exit
73
74
// Custom environment
75
shell.exec('echo $CUSTOM_VAR', {
76
env: { ...process.env, CUSTOM_VAR: 'custom_value' }
77
});
78
79
// Working directory
80
shell.exec('pwd', { cwd: '/tmp' });
81
```
82
83
### exit - Exit Process
84
85
Exits the current Node.js process with an optional exit code.
86
87
```javascript { .api }
88
/**
89
* Exit current process with optional exit code
90
* @param code - Exit code (default: 0 for success)
91
*/
92
function exit(code?: number): void;
93
```
94
95
**Usage Examples:**
96
97
```javascript
98
// Exit with success
99
shell.exit();
100
shell.exit(0);
101
102
// Exit with error code
103
shell.exit(1);
104
105
// Conditional exit
106
if (!shell.which('git')) {
107
shell.echo('Git is required');
108
shell.exit(1);
109
}
110
111
// Exit after error
112
if (shell.exec('npm test').code !== 0) {
113
shell.exit(1);
114
}
115
```
116
117
### pushd - Push Directory
118
119
Pushes the current directory onto the directory stack and optionally changes to a new directory.
120
121
```javascript { .api }
122
/**
123
* Push directory onto stack and optionally change to new directory
124
* @param options - Command options
125
* @param dir - Directory to change to, or stack position ('+N', '-N')
126
* @returns ShellString containing directory stack as array
127
*/
128
function pushd(options?: string, dir?: string): ShellString;
129
function pushd(dir?: string): ShellString;
130
```
131
132
**Options:**
133
- `-n`: Don't change directory, just manipulate stack
134
135
**Usage Examples:**
136
137
```javascript
138
// Push current directory and change to new one
139
const stack = shell.pushd('/path/to/directory');
140
console.log('Directory stack:', stack);
141
142
// Push without changing directory
143
shell.pushd('-n', '/another/path');
144
145
// Push current directory onto stack (no directory change)
146
shell.pushd();
147
148
// Navigate using stack positions
149
shell.pushd('+1'); // Rotate to second directory in stack
150
shell.pushd('-0'); // Move top of stack to current
151
```
152
153
### popd - Pop Directory
154
155
Pops a directory from the directory stack and optionally changes to it.
156
157
```javascript { .api }
158
/**
159
* Pop directory from stack and optionally change to it
160
* @param options - Command options
161
* @param dir - Stack position to pop ('+N', '-N')
162
* @returns ShellString containing directory stack as array
163
*/
164
function popd(options?: string, dir?: string): ShellString;
165
function popd(): ShellString;
166
```
167
168
**Options:**
169
- `-n`: Don't change directory, just manipulate stack
170
171
**Usage Examples:**
172
173
```javascript
174
// Pop and change to previous directory
175
const stack = shell.popd();
176
console.log('Returned to:', shell.pwd().toString());
177
178
// Pop specific stack position
179
shell.popd('+1'); // Pop second directory from stack
180
181
// Pop without changing directory
182
shell.popd('-n');
183
184
// Pop from bottom of stack
185
shell.popd('-0');
186
```
187
188
### dirs - Display Directory Stack
189
190
Displays the current directory stack with various formatting options.
191
192
```javascript { .api }
193
/**
194
* Display directory stack
195
* @param options - Display options or stack position ('+N', '-N')
196
* @returns ShellString containing directory stack as array
197
*/
198
function dirs(options?: string): ShellString;
199
function dirs(position: string): ShellString; // '+N' or '-N'
200
```
201
202
**Options:**
203
- `-c`: Clear the directory stack
204
- `-v`: Verbose output with stack positions
205
- `+N`: Show Nth directory from left (0-indexed)
206
- `-N`: Show Nth directory from right (0-indexed)
207
208
**Usage Examples:**
209
210
```javascript
211
// Show current directory stack
212
const stack = shell.dirs();
213
console.log('Stack:', stack);
214
215
// Verbose display with positions
216
shell.dirs('-v');
217
218
// Show specific position
219
const topDir = shell.dirs('+0'); // Top of stack
220
const bottomDir = shell.dirs('-0'); // Bottom of stack
221
222
// Clear directory stack
223
shell.dirs('-c');
224
225
// Use in loops
226
const stackArray = shell.dirs();
227
stackArray.forEach((dir, index) => {
228
console.log(`${index}: ${dir}`);
229
});
230
```
231
232
## Process Management Patterns
233
234
### Directory Navigation Workflows
235
236
```javascript
237
// Save current location, do work elsewhere, return
238
shell.pushd('/project/build');
239
shell.exec('make clean && make');
240
shell.popd(); // Return to original directory
241
242
// Navigate through multiple directories
243
shell.pushd('/logs');
244
const errors = shell.grep('ERROR', '*.log');
245
shell.pushd('/config');
246
const configs = shell.ls('*.conf');
247
shell.popd(); // Back to /logs
248
shell.popd(); // Back to original
249
250
// Complex navigation pattern
251
function processDirectories(dirs) {
252
dirs.forEach(dir => {
253
shell.pushd(dir);
254
shell.echo(`Processing ${shell.pwd()}`);
255
256
// Do work in each directory
257
shell.exec('npm test');
258
259
shell.popd();
260
});
261
}
262
```
263
264
### Command Execution Patterns
265
266
```javascript
267
// Build pipeline with error handling
268
function buildProject() {
269
shell.echo('Starting build...');
270
271
if (shell.exec('npm install').code !== 0) {
272
shell.echo('Failed to install dependencies');
273
shell.exit(1);
274
}
275
276
if (shell.exec('npm run lint').code !== 0) {
277
shell.echo('Linting failed');
278
shell.exit(1);
279
}
280
281
if (shell.exec('npm test').code !== 0) {
282
shell.echo('Tests failed');
283
shell.exit(1);
284
}
285
286
if (shell.exec('npm run build').code !== 0) {
287
shell.echo('Build failed');
288
shell.exit(1);
289
}
290
291
shell.echo('Build completed successfully');
292
}
293
294
// Async command execution
295
function deployAsync() {
296
shell.exec('docker build -t myapp .', { async: true }, function(code, stdout, stderr) {
297
if (code === 0) {
298
shell.echo('Build successful, deploying...');
299
shell.exec('docker push myapp', { async: true }, function(code, stdout, stderr) {
300
if (code === 0) {
301
shell.echo('Deploy successful');
302
} else {
303
shell.echo('Deploy failed:', stderr);
304
}
305
});
306
} else {
307
shell.echo('Build failed:', stderr);
308
}
309
});
310
}
311
312
// Environment-specific execution
313
function runTests(environment) {
314
const envVars = {
315
...process.env,
316
NODE_ENV: environment,
317
TEST_DB_URL: `mongodb://localhost/test_${environment}`
318
};
319
320
const result = shell.exec('npm test', {
321
env: envVars,
322
silent: true
323
});
324
325
if (result.code === 0) {
326
shell.echo(`✓ Tests passed in ${environment} environment`);
327
} else {
328
shell.echo(`✗ Tests failed in ${environment} environment`);
329
shell.echo(result.stderr);
330
}
331
332
return result.code === 0;
333
}
334
335
// Command chaining with validation
336
function validateAndDeploy() {
337
// Check prerequisites
338
if (!shell.which('docker')) {
339
shell.echo('Docker is required but not installed');
340
shell.exit(1);
341
}
342
343
if (!shell.which('git')) {
344
shell.echo('Git is required but not installed');
345
shell.exit(1);
346
}
347
348
// Validate git status
349
const status = shell.exec('git status --porcelain', { silent: true });
350
if (status.stdout.trim()) {
351
shell.echo('Working directory is not clean');
352
shell.exit(1);
353
}
354
355
// Execute deployment
356
const commands = [
357
'git pull origin main',
358
'npm ci',
359
'npm run build',
360
'docker build -t app:latest .',
361
'docker push app:latest'
362
];
363
364
for (const cmd of commands) {
365
shell.echo(`Executing: ${cmd}`);
366
if (shell.exec(cmd).code !== 0) {
367
shell.echo(`Command failed: ${cmd}`);
368
shell.exit(1);
369
}
370
}
371
372
shell.echo('Deployment completed successfully');
373
}
374
```
375
376
### Error Handling and Logging
377
378
```javascript
379
// Comprehensive error handling
380
function safeExec(command, options = {}) {
381
shell.echo(`Running: ${command}`);
382
383
const result = shell.exec(command, {
384
silent: true,
385
...options
386
});
387
388
if (result.code === 0) {
389
shell.echo(`✓ Success: ${command}`);
390
if (result.stdout && !options.silent) {
391
shell.echo(result.stdout);
392
}
393
} else {
394
shell.echo(`✗ Failed: ${command} (exit code: ${result.code})`);
395
if (result.stderr) {
396
shell.echo('Error output:', result.stderr);
397
}
398
399
if (options.fatal !== false) {
400
shell.exit(result.code);
401
}
402
}
403
404
return result;
405
}
406
407
// Usage
408
safeExec('npm test');
409
safeExec('optional-command', { fatal: false });
410
```