0
# Configuration and Utilities
1
2
Configuration system, error handling, environment variables, and utility functions for controlling ShellJS behavior and extending functionality.
3
4
## Capabilities
5
6
### config - Global Configuration
7
8
Global configuration object that controls the behavior of all ShellJS commands.
9
10
```javascript { .api }
11
/**
12
* Global configuration object for controlling ShellJS behavior
13
*/
14
const config: {
15
/** Suppress all command output if true (default: false) */
16
silent: boolean;
17
18
/** Throw JavaScript errors on command failures if true (default: false) */
19
fatal: boolean;
20
21
/** Print each command as it executes if true (default: false) */
22
verbose: boolean;
23
24
/** Options passed to fast-glob for file matching (deprecated) */
25
globOptions: object;
26
27
/** Path to Node.js executable (null for auto-detect) */
28
execPath: string | null;
29
30
/** Maximum directory depth for recursive operations (default: 255) */
31
maxdepth: number;
32
33
/** Disable glob expansion if true (default: false) */
34
noglob: boolean;
35
36
/** Buffer length for I/O operations (default: 64KB) */
37
bufLength: number;
38
39
/** Reset configuration to default values */
40
reset(): void;
41
};
42
```
43
44
**Usage Examples:**
45
46
```javascript
47
// Enable silent mode (suppress output)
48
shell.config.silent = true;
49
shell.ls(); // No output to console
50
51
// Enable fatal mode (throw errors on failures)
52
shell.config.fatal = true;
53
try {
54
shell.cp('nonexistent.txt', 'dest.txt'); // Throws error
55
} catch (e) {
56
console.log('Command failed:', e.message);
57
}
58
59
// Enable verbose mode (show commands)
60
shell.config.verbose = true;
61
shell.cd('mydir'); // Prints: cd mydir
62
63
// Save and restore configuration
64
const originalSilent = shell.config.silent;
65
shell.config.silent = true;
66
// ... do silent operations
67
shell.config.silent = originalSilent;
68
69
// Reset to defaults
70
shell.config.reset();
71
72
// Custom exec path (for bundled environments)
73
shell.config.execPath = '/custom/path/to/node';
74
75
// Disable glob expansion
76
shell.config.noglob = true;
77
shell.ls('*.txt'); // Treats *.txt literally, not as glob pattern
78
```
79
80
### env - Environment Variables
81
82
Direct access to environment variables as a convenient alias for `process.env`.
83
84
```javascript { .api }
85
/**
86
* Environment variables object (alias for process.env)
87
*/
88
const env: NodeJS.ProcessEnv;
89
```
90
91
**Usage Examples:**
92
93
```javascript
94
// Read environment variables
95
console.log('Home directory:', shell.env.HOME);
96
console.log('Path:', shell.env.PATH);
97
98
// Set environment variables
99
shell.env.NODE_ENV = 'production';
100
shell.env.CUSTOM_VAR = 'custom_value';
101
102
// Use in commands
103
const nodeVersion = shell.env.NODE_VERSION || '18';
104
shell.exec(`nvm use ${nodeVersion}`);
105
106
// Check if variable exists
107
if (shell.env.CI) {
108
shell.echo('Running in CI environment');
109
}
110
111
// Remove environment variable
112
delete shell.env.TEMP_VAR;
113
114
// Environment-aware operations
115
const configFile = shell.env.NODE_ENV === 'production'
116
? 'config.prod.json'
117
: 'config.dev.json';
118
```
119
120
### error - Error State Check
121
122
Returns the error message from the last command that failed, or null if no error occurred.
123
124
```javascript { .api }
125
/**
126
* Check if error occurred in the last command
127
* @returns Error message string if error occurred, null otherwise
128
*/
129
function error(): string | null;
130
```
131
132
**Usage Examples:**
133
134
```javascript
135
// Check for errors after commands
136
shell.cp('source.txt', 'dest.txt');
137
if (shell.error()) {
138
console.log('Copy failed:', shell.error());
139
}
140
141
// Error handling in loops
142
const files = ['file1.txt', 'file2.txt', 'file3.txt'];
143
files.forEach(file => {
144
shell.cp(file, 'backup/');
145
if (shell.error()) {
146
console.log(`Failed to backup ${file}:`, shell.error());
147
}
148
});
149
150
// Conditional logic based on errors
151
shell.mkdir('new_directory');
152
if (!shell.error()) {
153
shell.echo('Directory created successfully');
154
shell.cd('new_directory');
155
}
156
157
// Clear error state (done automatically by next command)
158
shell.rm('nonexistent.txt'); // Sets error
159
console.log(shell.error()); // Shows error message
160
shell.echo('test'); // Clears error state
161
console.log(shell.error()); // Returns null
162
```
163
164
### errorCode - Error Code Check
165
166
Returns the numeric error code from the last command, or 0 if no error occurred.
167
168
```javascript { .api }
169
/**
170
* Get error code from the last command
171
* @returns Numeric error code (0 for success, non-zero for errors)
172
*/
173
function errorCode(): number;
174
```
175
176
**Usage Examples:**
177
178
```javascript
179
// Check error codes
180
shell.exec('npm test');
181
if (shell.errorCode() !== 0) {
182
shell.echo(`Tests failed with code ${shell.errorCode()}`);
183
shell.exit(shell.errorCode());
184
}
185
186
// Compare error codes
187
shell.rm('protected_file.txt');
188
const code = shell.errorCode();
189
switch (code) {
190
case 0:
191
shell.echo('File removed successfully');
192
break;
193
case 1:
194
shell.echo('Permission denied');
195
break;
196
case 2:
197
shell.echo('File not found');
198
break;
199
default:
200
shell.echo(`Unknown error: ${code}`);
201
}
202
203
// Use error codes for flow control
204
function tryOperation() {
205
shell.mkdir('temp_dir');
206
if (shell.errorCode() === 0) {
207
// Success path
208
shell.cd('temp_dir');
209
return true;
210
} else {
211
// Error path
212
return false;
213
}
214
}
215
```
216
217
### set - Set Shell Options
218
219
Sets shell options similar to the bash `set` command, providing an alternative way to configure behavior.
220
221
```javascript { .api }
222
/**
223
* Set shell options (similar to bash set command)
224
* @param options - Option string (e.g., '-e', '+e', '-v', '+v')
225
* @returns ShellString with operation result
226
*/
227
function set(options: string): ShellString;
228
```
229
230
**Options:**
231
- `-e` / `+e`: Enable/disable exit on error (sets config.fatal)
232
- `-v` / `+v`: Enable/disable verbose mode (sets config.verbose)
233
- `-f` / `+f`: Disable/enable filename expansion (globbing) (sets config.noglob)
234
235
**Usage Examples:**
236
237
```javascript
238
// Enable exit on error
239
shell.set('-e');
240
shell.cp('nonexistent.txt', 'dest.txt'); // Will throw error
241
242
// Disable exit on error
243
shell.set('+e');
244
shell.cp('nonexistent.txt', 'dest.txt'); // Won't throw, sets error state
245
246
// Enable verbose mode
247
shell.set('-v');
248
shell.ls(); // Shows command before execution
249
250
// Disable verbose mode
251
shell.set('+v');
252
253
// Disable globbing
254
shell.set('-f');
255
shell.ls('*.txt'); // Treats *.txt literally, not as pattern
256
257
// Enable globbing
258
shell.set('+f');
259
shell.ls('*.txt'); // Expands *.txt pattern
260
261
// Multiple options
262
shell.set('-ev'); // Enable both error exit and verbose mode
263
264
// Use in scripts for strict error handling
265
shell.set('-e'); // Exit on any error
266
shell.exec('npm install');
267
shell.exec('npm test');
268
shell.exec('npm run build');
269
// Script will exit early if any command fails
270
```
271
272
### ShellString - Command Return Type
273
274
The return type for most ShellJS commands, extending String with additional properties and methods for command chaining and file operations.
275
276
```javascript { .api }
277
/**
278
* ShellJS command return type with additional properties and methods
279
*/
280
class ShellString extends String {
281
/** Standard output from the command */
282
stdout: string;
283
284
/** Standard error output from the command */
285
stderr: string;
286
287
/** Exit code from the command (0 for success) */
288
code: number;
289
290
/**
291
* Create a new ShellString
292
* @param stdout - Standard output content
293
* @param stderr - Standard error content
294
* @param code - Exit code
295
*/
296
constructor(stdout: string | string[], stderr?: string, code?: number);
297
298
/**
299
* Write ShellString content to file (overwrite)
300
* @param file - Target file path
301
* @returns Same ShellString for chaining
302
*/
303
to(file: string): ShellString;
304
305
/**
306
* Append ShellString content to file
307
* @param file - Target file path
308
* @returns Same ShellString for chaining
309
*/
310
toEnd(file: string): ShellString;
311
}
312
```
313
314
**Usage Examples:**
315
316
```javascript
317
// Access command output properties
318
const result = shell.exec('ls -la');
319
console.log('Exit code:', result.code);
320
console.log('Output:', result.stdout);
321
console.log('Errors:', result.stderr);
322
323
// Use as string
324
const files = shell.ls();
325
console.log('Files:', files.toString());
326
console.log('Count:', files.split('\n').length);
327
328
// Method chaining with file output
329
shell.cat('input.txt')
330
.sed('old', 'new')
331
.to('output.txt');
332
333
// Pipe to append
334
shell.echo('Log entry: ' + new Date())
335
.toEnd('application.log');
336
337
// Create custom ShellString
338
const customResult = new shell.ShellString('custom output', '', 0);
339
customResult.to('custom.txt');
340
341
// Check for command success
342
const gitStatus = shell.exec('git status', { silent: true });
343
if (gitStatus.code === 0) {
344
console.log('Git repository is clean');
345
} else {
346
console.log('Git error:', gitStatus.stderr);
347
}
348
349
// Array-like behavior for some commands
350
const fileList = shell.ls();
351
fileList.forEach(file => {
352
console.log('Processing:', file);
353
});
354
```
355
356
## Plugin System
357
358
ShellJS provides a plugin system for extending functionality with custom commands.
359
360
### Plugin Utilities
361
362
```javascript { .api }
363
/**
364
* Plugin utilities for extending ShellJS (from 'shelljs/plugin')
365
*/
366
interface PluginAPI {
367
/** Register a new command */
368
register(name: string, implementation: Function, options?: RegisterOptions): void;
369
370
/** Signal errors from within commands */
371
error(message: string, code?: number, options?: ErrorOptions): void;
372
373
/** Parse command options */
374
parseOptions(optionString: string, optionMap: object, options?: ParseOptions): object;
375
376
/** Read input from pipe for commands that accept piped input */
377
readFromPipe(): string;
378
}
379
380
interface RegisterOptions {
381
/** Allow command to receive piped input */
382
canReceivePipe?: boolean;
383
384
/** Command-specific option definitions */
385
cmdOptions?: object;
386
387
/** Allow glob patterns in arguments */
388
allowGlobbing?: boolean;
389
390
/** Use Unix-style behavior */
391
unix?: boolean;
392
393
/** Don't wrap output in ShellString */
394
wrapOutput?: boolean;
395
}
396
```
397
398
**Usage Examples:**
399
400
```javascript
401
// Create a plugin file
402
const shell = require('shelljs');
403
const plugin = require('shelljs/plugin');
404
405
// Register a custom command
406
plugin.register('count', countLines, {
407
canReceivePipe: true,
408
cmdOptions: {
409
'l': 'lines',
410
'w': 'words',
411
'c': 'chars'
412
}
413
});
414
415
function countLines(options, ...files) {
416
// Get piped input if available
417
let input = plugin.readFromPipe();
418
419
// Parse options
420
const opts = plugin.parseOptions(options, {
421
'l': 'lines',
422
'w': 'words',
423
'c': 'chars'
424
});
425
426
// Implementation
427
if (!input && files.length === 0) {
428
plugin.error('No input provided');
429
return;
430
}
431
432
// Process files or input
433
const content = input || shell.cat(files).toString();
434
const lines = content.split('\n').length;
435
const words = content.split(/\s+/).length;
436
const chars = content.length;
437
438
if (opts.lines) return lines;
439
if (opts.words) return words;
440
if (opts.chars) return chars;
441
442
return `${lines} ${words} ${chars}`;
443
}
444
445
// Use the custom command
446
shell.count('file.txt');
447
shell.cat('file.txt').count('-l');
448
```
449
450
## Make System
451
452
ShellJS includes a make-like build system for task automation.
453
454
```javascript { .api }
455
/**
456
* Make system for task automation (from 'shelljs/make')
457
*/
458
const target: {
459
[targetName: string]: (args?: string[]) => any;
460
};
461
```
462
463
**Usage Examples:**
464
465
```javascript
466
// In a make.js file
467
require('shelljs/make');
468
469
target.all = function() {
470
target.build();
471
target.test();
472
};
473
474
target.build = function() {
475
shell.echo('Building project...');
476
shell.exec('npm run build');
477
};
478
479
target.test = function() {
480
shell.echo('Running tests...');
481
shell.exec('npm test');
482
};
483
484
target.clean = function() {
485
shell.echo('Cleaning build artifacts...');
486
shell.rm('-rf', 'dist/');
487
shell.rm('-rf', 'coverage/');
488
};
489
490
target.deploy = function(args) {
491
const env = args && args[0] || 'staging';
492
shell.echo(`Deploying to ${env}...`);
493
shell.exec(`npm run deploy:${env}`);
494
};
495
496
// Run with: node make.js build
497
// Run with: node make.js deploy production
498
// Run with: node make.js --help
499
```
500
501
## Configuration Patterns
502
503
### Environment-Aware Configuration
504
505
```javascript
506
// Setup based on environment
507
function configureShell() {
508
if (shell.env.NODE_ENV === 'production') {
509
shell.config.silent = true;
510
shell.config.fatal = true;
511
} else if (shell.env.NODE_ENV === 'development') {
512
shell.config.verbose = true;
513
}
514
515
// CI environment settings
516
if (shell.env.CI) {
517
shell.config.silent = true;
518
shell.config.fatal = true;
519
}
520
}
521
522
// Scoped configuration changes
523
function withSilentMode(callback) {
524
const originalSilent = shell.config.silent;
525
shell.config.silent = true;
526
527
try {
528
return callback();
529
} finally {
530
shell.config.silent = originalSilent;
531
}
532
}
533
534
// Usage
535
const result = withSilentMode(() => {
536
return shell.exec('npm list --depth=0');
537
});
538
```
539
540
### Error Handling Strategies
541
542
```javascript
543
// Comprehensive error checking
544
function robustOperation() {
545
// Method 1: Check error state
546
shell.mkdir('temp');
547
if (shell.error()) {
548
console.log('Failed to create directory:', shell.error());
549
return false;
550
}
551
552
// Method 2: Check error code
553
shell.cp('source.txt', 'temp/');
554
if (shell.errorCode() !== 0) {
555
console.log('Copy failed with code:', shell.errorCode());
556
return false;
557
}
558
559
// Method 3: Use fatal mode with try/catch
560
const originalFatal = shell.config.fatal;
561
shell.config.fatal = true;
562
563
try {
564
shell.exec('npm install');
565
shell.exec('npm test');
566
return true;
567
} catch (e) {
568
console.log('Command failed:', e.message);
569
return false;
570
} finally {
571
shell.config.fatal = originalFatal;
572
}
573
}
574
```