shelljs-ffi

A close fork of shelljs that replaces the unreliable hacky execSync with another based on node-ffi.

ShellJS - Unix shell commands for Node.js

ShellJS 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!

The project is unit-tested and battled-tested in projects like:

  • PDF.js - Firefox's next-gen PDF reader
  • Firebug - Firefox's infamous debugger
  • JSHint - Most popular JavaScript linter
  • Zepto - jQuery-compatible JavaScript library for modern browsers
  • Yeoman - Web application stack and development tool
  • Deployd.com - Open source PaaS for quick API backend generation

and many more.

Via npm:

$ npm install [-g] shelljs

If the global option -g is specified, the binary shjs will be installed. This makes it possible to run ShellJS scripts much like any shell script from the command line, i.e. without requiring a node_modules folder:

$ shjs my_script

You can also just copy shell.js into your project's directory, and require() accordingly.

require('shelljs/global');
 
if (!which('git')) {
  echo('Sorry, this script requires git');
  exit(1);
}
 
// Copy files to release dir 
mkdir('-p', 'out/Release');
cp('-R', 'stuff/*', 'out/Release');
 
// Replace macros in each .js file 
cd('lib');
ls('*.js').forEach(function(file) {
  sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
  sed('-i', /.*REMOVE_THIS_LINE.*\n/, '', file);
  sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat('macro.js'), file);
});
cd('..');
 
// Run external tool synchronously 
if (exec('git commit -am "Auto-commit"').code !== 0) {
  echo('Error: Git commit failed');
  exit(1);
}
require 'shelljs/global'
 
if not which 'git'
  echo 'Sorry, this script requires git'
  exit 1
 
# Copy files to release dir 
mkdir '-p''out/Release'
cp '-R''stuff/*''out/Release'
 
# Replace macros in each .js file 
cd 'lib'
for file in ls '*.js'
  sed '-i''BUILD_VERSION''v0.1.2'file
  sed '-i'/.*REMOVE_THIS_LINE.*\n/''file
  sed '-i'/.*REPLACE_LINE_WITH_MACRO.*\n/cat 'macro.js'file
cd '..'
 
# Run external tool synchronously 
if (exec 'git commit -am "Auto-commit"').code != 0
  echo 'Error: Git commit failed'
  exit 1

The example above uses the convenience script shelljs/global to reduce verbosity. If polluting your global namespace is not desirable, simply require shelljs.

Example:

var shell = require('shelljs');
shell.echo('hello world');

A 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.

Example (CoffeeScript):

require 'shelljs/make'
 
target.all = ->
  target.bundle()
  target.docs()
 
target.bundle = ->
  cd __dirname
  mkdir 'build'
  cd 'lib'
  (cat '*.js').to '../build/output.js'
 
target.docs = ->
  cd __dirname
  mkdir 'docs'
  cd 'lib'
  for file in ls '*.js'
    text = grep '//@'file     # extract special comments 
    text.replace '//@'''      # remove comment tags 
    text.to 'docs/my_docs.md'

To run the target all, call the above script without arguments: $ node make. To run the target docs: $ node make docs, and so on.