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