1# ShellJS - Unix shell commands for Node.js [![Build Status](https://secure.travis-ci.org/arturadib/shelljs.png)](http://travis-ci.org/arturadib/shelljs)
2
3ShellJS is a portable **(Windows/Linux/OS X)** implementation of Unix shell commands on top of the Node.js API. You can use it to eliminate your shell script's dependency on Unix while still keeping its familiar and powerful commands. You can also install it globally so you can run it from outside Node projects - say goodbye to those gnarly Bash scripts!
4
5The project is [unit-tested](http://travis-ci.org/arturadib/shelljs) and battled-tested in projects like:
6
7+ [PDF.js](http://github.com/mozilla/pdf.js) - Firefox's next-gen PDF reader
8+ [Firebug](http://getfirebug.com/) - Firefox's infamous debugger
9+ [JSHint](http://jshint.com) - Most popular JavaScript linter
10+ [Zepto](http://zeptojs.com) - jQuery-compatible JavaScript library for modern browsers
11+ [Yeoman](http://yeoman.io/) - Web application stack and development tool
12+ [Deployd.com](http://deployd.com) - Open source PaaS for quick API backend generation
13
14and [many more](https://npmjs.org/browse/depended/shelljs).
15
16## Installing
17
18Via npm:
19
20```bash
21$ npm install [-g] shelljs
22```
23
24If the global option `-g` is specified, the binary `shjs` will be installed. This makes it possible to
25run ShellJS scripts much like any shell script from the command line, i.e. without requiring a `node_modules` folder:
26
27```bash
28$ shjs my_script
29```
30
31You can also just copy `shell.js` into your project's directory, and `require()` accordingly.
32
33
34## Examples
35
36### JavaScript
37
38```javascript
39require('shelljs/global');
40
41if (!which('git')) {
42  echo('Sorry, this script requires git');
43  exit(1);
44}
45
46// Copy files to release dir
47mkdir('-p', 'out/Release');
48cp('-R', 'stuff/*', 'out/Release');
49
50// Replace macros in each .js file
51cd('lib');
52ls('*.js').forEach(function(file) {
53  sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
54  sed('-i', /.*REMOVE_THIS_LINE.*\n/, '', file);
55  sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat('macro.js'), file);
56});
57cd('..');
58
59// Run external tool synchronously
60if (exec('git commit -am "Auto-commit"').code !== 0) {
61  echo('Error: Git commit failed');
62  exit(1);
63}
64```
65
66### CoffeeScript
67
68```coffeescript
69require 'shelljs/global'
70
71if not which 'git'
72  echo 'Sorry, this script requires git'
73  exit 1
74
75# Copy files to release dir
76mkdir '-p', 'out/Release'
77cp '-R', 'stuff/*', 'out/Release'
78
79# Replace macros in each .js file
80cd 'lib'
81for file in ls '*.js'
82  sed '-i', 'BUILD_VERSION', 'v0.1.2', file
83  sed '-i', /.*REMOVE_THIS_LINE.*\n/, '', file
84  sed '-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat 'macro.js', file
85cd '..'
86
87# Run external tool synchronously
88if (exec 'git commit -am "Auto-commit"').code != 0
89  echo 'Error: Git commit failed'
90  exit 1
91```
92
93## Global vs. Local
94
95The example above uses the convenience script `shelljs/global` to reduce verbosity. If polluting your global namespace is not desirable, simply require `shelljs`.
96
97Example:
98
99```javascript
100var shell = require('shelljs');
101shell.echo('hello world');
102```
103
104## Make tool
105
106A convenience script `shelljs/make` is also provided to mimic the behavior of a Unix Makefile. In this case all shell objects are global, and command line arguments will cause the script to execute only the corresponding function in the global `target` object. To avoid redundant calls, target functions are executed only once per script.
107
108Example (CoffeeScript):
109
110```coffeescript
111require 'shelljs/make'
112
113target.all = ->
114  target.bundle()
115  target.docs()
116
117target.bundle = ->
118  cd __dirname
119  mkdir 'build'
120  cd 'lib'
121  (cat '*.js').to '../build/output.js'
122
123target.docs = ->
124  cd __dirname
125  mkdir 'docs'
126  cd 'lib'
127  for file in ls '*.js'
128    text = grep '//@', file     # extract special comments
129    text.replace '//@', ''      # remove comment tags
130    text.to 'docs/my_docs.md'
131```
132
133To run the target `all`, call the above script without arguments: `$ node make`. To run the target `docs`: `$ node make docs`, and so on.
134
135
136
137<!--
138
139  DO NOT MODIFY BEYOND THIS POINT - IT'S AUTOMATICALLY GENERATED
140
141-->
142
143
144## Command reference
145
146
147All commands run synchronously, unless otherwise stated.
148
149
150### cd('dir')
151Changes to directory `dir` for the duration of the script
152
153
154### pwd()
155Returns the current directory.
156
157
158### ls([options ,] path [,path ...])
159### ls([options ,] path_array)
160Available options:
161
162+ `-R`: recursive
163+ `-A`: all files (include files beginning with `.`, except for `.` and `..`)
164
165Examples:
166
167```javascript
168ls('projs/*.js');
169ls('-R', '/users/me', '/tmp');
170ls('-R', ['/users/me', '/tmp']); // same as above
171```
172
173Returns array of files in the given path, or in current directory if no path provided.
174
175
176### find(path [,path ...])
177### find(path_array)
178Examples:
179
180```javascript
181find('src', 'lib');
182find(['src', 'lib']); // same as above
183find('.').filter(function(file) { return file.match(/\.js$/); });
184```
185
186Returns array of all files (however deep) in the given paths.
187
188The main difference from `ls('-R', path)` is that the resulting file names
189include the base directories, e.g. `lib/resources/file1` instead of just `file1`.
190
191
192### cp([options ,] source [,source ...], dest)
193### cp([options ,] source_array, dest)
194Available options:
195
196+ `-f`: force
197+ `-r, -R`: recursive
198
199Examples:
200
201```javascript
202cp('file1', 'dir1');
203cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
204cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
205```
206
207Copies files. The wildcard `*` is accepted.
208
209
210### rm([options ,] file [, file ...])
211### rm([options ,] file_array)
212Available options:
213
214+ `-f`: force
215+ `-r, -R`: recursive
216
217Examples:
218
219```javascript
220rm('-rf', '/tmp/*');
221rm('some_file.txt', 'another_file.txt');
222rm(['some_file.txt', 'another_file.txt']); // same as above
223```
224
225Removes files. The wildcard `*` is accepted.
226
227
228### mv(source [, source ...], dest')
229### mv(source_array, dest')
230Available options:
231
232+ `f`: force
233
234Examples:
235
236```javascript
237mv('-f', 'file', 'dir/');
238mv('file1', 'file2', 'dir/');
239mv(['file1', 'file2'], 'dir/'); // same as above
240```
241
242Moves files. The wildcard `*` is accepted.
243
244
245### mkdir([options ,] dir [, dir ...])
246### mkdir([options ,] dir_array)
247Available options:
248
249+ `p`: full path (will create intermediate dirs if necessary)
250
251Examples:
252
253```javascript
254mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');
255mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above
256```
257
258Creates directories.
259
260
261### test(expression)
262Available expression primaries:
263
264+ `'-b', 'path'`: true if path is a block device
265+ `'-c', 'path'`: true if path is a character device
266+ `'-d', 'path'`: true if path is a directory
267+ `'-e', 'path'`: true if path exists
268+ `'-f', 'path'`: true if path is a regular file
269+ `'-L', 'path'`: true if path is a symboilc link
270+ `'-p', 'path'`: true if path is a pipe (FIFO)
271+ `'-S', 'path'`: true if path is a socket
272
273Examples:
274
275```javascript
276if (test('-d', path)) { /* do something with dir */ };
277if (!test('-f', path)) continue; // skip if it's a regular file
278```
279
280Evaluates expression using the available primaries and returns corresponding value.
281
282
283### cat(file [, file ...])
284### cat(file_array)
285
286Examples:
287
288```javascript
289var str = cat('file*.txt');
290var str = cat('file1', 'file2');
291var str = cat(['file1', 'file2']); // same as above
292```
293
294Returns a string containing the given file, or a concatenated string
295containing the files if more than one file is given (a new line character is
296introduced between each file). Wildcard `*` accepted.
297
298
299### 'string'.to(file)
300
301Examples:
302
303```javascript
304cat('input.txt').to('output.txt');
305```
306
307Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as
308those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_
309
310
311### 'string'.toEnd(file)
312
313Examples:
314
315```javascript
316cat('input.txt').toEnd('output.txt');
317```
318
319Analogous to the redirect-and-append operator `>>` in Unix, but works with JavaScript strings (such as
320those returned by `cat`, `grep`, etc).
321
322
323### sed([options ,] search_regex, replace_str, file)
324Available options:
325
326+ `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_
327
328Examples:
329
330```javascript
331sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
332sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
333```
334
335Reads an input string from `file` and performs a JavaScript `replace()` on the input
336using the given search regex and replacement string. Returns the new string after replacement.
337
338
339### grep([options ,] regex_filter, file [, file ...])
340### grep([options ,] regex_filter, file_array)
341Available options:
342
343+ `-v`: Inverse the sense of the regex and print the lines not matching the criteria.
344
345Examples:
346
347```javascript
348grep('-v', 'GLOBAL_VARIABLE', '*.js');
349grep('GLOBAL_VARIABLE', '*.js');
350```
351
352Reads input string from given files and returns a string containing all lines of the
353file that match the given `regex_filter`. Wildcard `*` accepted.
354
355
356### which(command)
357
358Examples:
359
360```javascript
361var nodeExec = which('node');
362```
363
364Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.
365Returns string containing the absolute path to the command.
366
367
368### echo(string [,string ...])
369
370Examples:
371
372```javascript
373echo('hello world');
374var str = echo('hello world');
375```
376
377Prints string to stdout, and returns string with additional utility methods
378like `.to()`.
379
380
381### pushd([options,] [dir | '-N' | '+N'])
382
383Available options:
384
385+ `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated.
386
387Arguments:
388
389+ `dir`: Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir`.
390+ `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
391+ `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
392
393Examples:
394
395```javascript
396// process.cwd() === '/usr'
397pushd('/etc'); // Returns /etc /usr
398pushd('+1');   // Returns /usr /etc
399```
400
401Save the current directory on the top of the directory stack and then cd to `dir`. With no arguments, pushd exchanges the top two directories. Returns an array of paths in the stack.
402
403### popd([options,] ['-N' | '+N'])
404
405Available options:
406
407+ `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated.
408
409Arguments:
410
411+ `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero.
412+ `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero.
413
414Examples:
415
416```javascript
417echo(process.cwd()); // '/usr'
418pushd('/etc');       // '/etc /usr'
419echo(process.cwd()); // '/etc'
420popd();              // '/usr'
421echo(process.cwd()); // '/usr'
422```
423
424When no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs; i.e., popd is equivalent to popd +0. Returns an array of paths in the stack.
425
426### dirs([options | '+N' | '-N'])
427
428Available options:
429
430+ `-c`: Clears the directory stack by deleting all of the elements.
431
432Arguments:
433
434+ `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero.
435+ `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero.
436
437Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified.
438
439See also: pushd, popd
440
441
442### exit(code)
443Exits the current process with the given exit code.
444
445### env['VAR_NAME']
446Object containing environment variables (both getter and setter). Shortcut to process.env.
447
448### exec(command [, options] [, callback])
449Available options (all `false` by default):
450
451+ `async`: Asynchronous execution. Defaults to true if a callback is provided.
452+ `silent`: Do not echo program output to console.
453
454Examples:
455
456```javascript
457var version = exec('node --version', {silent:true}).output;
458
459var child = exec('some_long_running_process', {async:true});
460child.stdout.on('data', function(data) {
461  /* ... do something with data ... */
462});
463
464exec('some_long_running_process', function(code, output) {
465  console.log('Exit code:', code);
466  console.log('Program output:', output);
467});
468```
469
470Executes the given `command` _synchronously_, unless otherwise specified.
471When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's
472`output` (stdout + stderr)  and its exit `code`. Otherwise returns the child process object, and
473the `callback` gets the arguments `(code, output)`.
474
475**Note:** For long-lived processes, it's best to run `exec()` asynchronously as
476the current synchronous implementation uses a lot of CPU. This should be getting
477fixed soon.
478
479
480### chmod(octal_mode || octal_string, file)
481### chmod(symbolic_mode, file)
482
483Available options:
484
485+ `-v`: output a diagnostic for every file processed
486+ `-c`: like verbose but report only when a change is made
487+ `-R`: change files and directories recursively
488
489Examples:
490
491```javascript
492chmod(755, '/Users/brandon');
493chmod('755', '/Users/brandon'); // same as above
494chmod('u+x', '/Users/brandon');
495```
496
497Alters the permissions of a file or directory by either specifying the
498absolute permissions in octal form or expressing the changes in symbols.
499This command tries to mimic the POSIX behavior as much as possible.
500Notable exceptions:
501
502+ In symbolic modes, 'a-r' and '-r' are identical.  No consideration is
503  given to the umask.
504+ There is no "quiet" option since default behavior is to run silent.
505
506
507## Non-Unix commands
508
509
510### tempdir()
511
512Examples:
513
514```javascript
515var tmp = tempdir(); // "/tmp" for most *nix platforms
516```
517
518Searches and returns string containing a writeable, platform-dependent temporary directory.
519Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).
520
521
522### error()
523Tests if error occurred in the last command. Returns `null` if no error occurred,
524otherwise returns string explaining the error
525
526
527## Configuration
528
529
530### config.silent
531Example:
532
533```javascript
534var silentState = config.silent; // save old silent state
535config.silent = true;
536/* ... */
537config.silent = silentState; // restore old silent state
538```
539
540Suppresses all command output if `true`, except for `echo()` calls.
541Default is `false`.
542
543### config.fatal
544Example:
545
546```javascript
547config.fatal = true;
548cp('this_file_does_not_exist', '/dev/null'); // dies here
549/* more commands... */
550```
551
552If `true` the script will die on errors. Default is `false`.
553