Unix: It's Alive!

13 May 2013 | By Alex Young | Tags node modules unix

On a philosophical level, Node developers love Unix. I like to think that’s why Node’s core modules are relatively lightweight compared to other standard libraries (is an FTP library really necessary?) – Node’s modules quietly get out of the way, allowing the community to provide solutions to higher-level problems.

As someone who sits inside tmux/Vim/ssh all day, I’m preoccupied with command-line tools and ways to work more efficiently in the shell. That’s why I was intrigued to find bashful (GitHub: substack / bashful, License: MIT, npm: bashful) by substack. It allows Bash to be parsed and executed. To use it, hook it up with some streams:

var bash = require('bashful')(process.env);
bash.on('command', require('child_process').spawn);

var s = bash.createStream();
process.stdin.pipe(s).pipe(process.stdout);

After installing bashful, running this example with node sh.js will allow you to issue shell commands. Not all of Bash’s built-in commands are supported yet (there’s a list and to-do in the readme), but you should be able to execute commands and run true and false, then get the last exit status with echo $?.

How does this work? Well, the bashful module basically parses each line, character-by-character, to tokenise the input. It then checks anything that looks like a command against the list of built-in commands, and runs it. It mixes Node streams with a JavaScript bash parser to create a Bash-like layer that you can reuse with other streams.

This module depends on shell-quote, which correctly escapes those gnarly quotes in shell commands. I expect substack will make a few more shell-related modules as he continues work on bashful.

ShellJS (GitHub: arturadib / shelljs, npm: shelljs) by Artur Adib has been around for a while, but still receives regular updates. This module gives you shell-like commands in Node:

require('shelljs/global');

mkdir('-p', 'out/Release');
cp('-R', 'stuff/*', 'out/Release');

It can even mimic Make, so you could write your build scripts with it. This would make sense if you’re sharing code with Windows-based developers.

There are plenty of other interesting Unix-related modules that are alive and regularly updated. One I was looking at recently is suppose (GitHub: jprichardson / node-suppose, License: MIT, npm: suppose) by JP Richardson, which is an expect(1) clone:

var suppose = require('suppose')
  , fs = require('fs')
  , assert = require('assert')

suppose('npm', ['init'])
  .debug(fs.createWriteStream('/tmp/debug.txt'))
  .on(/name\: \([\w|\-]+\)[\s]*/).respond('awesome_package\n')
  .on('version: (0.0.0) ').respond('0.0.1\n')
  // ...

It uses a chainable API to allow expect-like expressions to capture and react to the output of other programs.

Unix in the Node community is alive and well, but I’m sure there’s also lots of Windows-related fun to be had – assuming you can figure out how to use Windows 9 with a keyboard and mouse that is…


blog comments powered by Disqus