Skip to content

Passing options to node on the shebang (#!) line


I was chatting with someone on #node.js who wanted his script to pass a command-line option to node, so that his script was run in a particular node environment. The problem is that under linux you get to pass exactly one argument on the shebang (#!) line. If you use #!/usr/bin/env node, you’ve already used your one argument. When I suggested he use the “-x” hack, we discovered that node didn’t have this hack. So I made a pull request complete with a TL;DR justification for why -x is necessary.

Turns out there’s a tidier hack that doesn’t require any changes to node, which relies on the interaction between bash and node.  Here’s an example, lifted from pm2 and lightly modified for clarity:

":" //# comment; exec /usr/bin/env node --noharmony "$0" "$@"


Here’s how it works:

  1. The #!/bin/sh causes the script to be identified as a shell script, and passed to /bin/sh for execution. /bin/sh reads and executes scripts one line at a time, and we’re taking advantage of that below.

  2. The second line, as interpreted by the shell, consists of two commands.

    2a. The first command is ":", which is the quoted version of the rarely-used bash command :, which means “expand arguments and no-op”. The only argument to : is //, which is a valid path. The following # is a bash comment, which is valid until the command separator ;.

    2b. The second command is exec /usr/bin/env node --noharmony "$0" "$@" which executes the node interpreter with the desired arguments and passes argument 0 (this script file) and the rest of the arguments to the bash script ("$@")

  3. The exec causes the bash process to be replaced by the node process, so bash does not attempt to process any further lines.

Now we’re running under node, with the desired command line arguments set. Unlike bash, node wants to read and parse the whole file. So let’s see what node sees:

  1. The #!/bin/sh line is ignored due to a special one-off in node – when loading a module, the contents of the first line will be ignored from #! up to the first \n.
  2. The second line contains a string constant, the quoted string ":", followed by a Javascript comment introduced with //. Automatic semicolon insertion happens so the constant is interpreted as a string in a statement context. Then the comment is parsed, and everything up to the end of the line is ignored by node.

This won’t lint clean. jslint and jshint both complain:

$ jslint test
test:2:1: Expected an assignment or function call and instead saw an expression.
test:2:4: Expected ';' and instead saw 'console'.
$ jshint test
test: line 2, col 1, Missing semicolon.

1 error

But it works right now, as a hack-around for the Linux one-argument shebang problem.

Note that there’s a spot in the line where you can insert a comment (as long as it doesn’t contain anything that bash interprets, notably ;). What to put there? I recommend a link to a web page (such as the one you’re reading now, that explains WTF this weird-looking line is all about. For example:

":" //# ; exec /usr/bin/env node --noharmony "$0" "$@"


Happy hacking!

Teaching Editing and Dictation


The day before yesterday we practiced editing and dictation (#4 and #3).  For editing, I found an essay online that Kaija wouldn’t hate to read (it’s about Pokemon).  I asked her to read it out loud to me.  Afterward, we went over it with a highlighter and pen and I summarized each paragraph in a single sentence and pointed out places where the wording or structure of the essay was weak.

Then I chose a paragraph at random from a nearby book — 3D Game Programming for Kids — and dictated it to her in my best French-teacher style – read it once through for context, once again slowly, repeating each sentence, and one last time for proofreading.

Dictating is more work than I expected.  I had to identify the words she might have difficulty spelling (“sphere” and “pyramid”) and write them out for her where she could see them.  I had to decide whether to pronounce the punctuation (not the first or last times, yes the second time).  I hadn’t realized that giving dictation is a skill, but it turns out to be one, and one I haven’t practiced.

Learning By Breaking It Down


When learning how to do something, it helps to break it down to irreducible subtasks.

As an example, we homeschool our kids; my eldest daughter Kaija is 5th-grade age.  We want her to practice writing simple paragraphs as a stepping stone to essays.  But asking her to just “write a paragraph” can be overwhelming, because in order to “write a paragraph” you have to do all the following subtasks:

  1. choose a topic
  2. structure your thoughts into coherent sentences
  3. write the sentences down
  4. proofread and edit
  5. make a fair copy

So following the advice of Susan Wise Bauer, we try to create opportunities for her to practice these subtasks in isolation.

Today we did #2, structure your thoughts.  I chose a topic: I said “tell me something about William the Silent.”  Kaija told me what to write and I wrote it down, so:

William the Silent was born in Germany.  He was brought to Spain to learn royal manners.  He was born a Protestant, so the king of Spain was worried he would not be loyal.  In Spain William learned how to be a Catholic.

When William grew up, he was given control of he Netherlands, which still belonged to Spain at that time.  Philip, the King of Spain, wanted to destroy Protestantism in the Netherlands.  William and the Dutch people waged a war for independence.  William became the first king of the Netherlands.


Dim Glimmers of Light


A lot of change this year.

At the beginning of 2013 I said ‘goodbye’ to a longtime client (15 years).  It was time, and past time.

Getting all my stuff sorted out and handed over took a while: I planned three months, it took only two, so I picked up and knocked off one more major and minor project before I finished.  We also moved the source control from CVS to SVN in January.  That was fun; I put together a training presentation.  (Why not git?  Baby steps, man.  You gotta walk before you run, etc.)

From April-May I took about 8 weeks off, drove down to the US with the kids, hung out with a lot of old friends.  D was able to get one weekend off (she was working Emerg, so time is a bit more flexible) and so she flew down and we went to her 15-year reunion at Mudd.

On the trip I figured out what I want to do for my next project.  That’s still dark, though I’ve showed it to a bunch of people.  If you want to see it, drop me an email and I can show you the very rough alpha.

Summer & Fall – I must have been working, but there was a lot of fuzzy front-end stuff.  Choice of language (settled on Javascript), platforms, wireframes, UX design, thinking a lot about the problem domain.

I’m hoping to do a closed alpha in January and open beta next summer, aiming for a Q3 launch.

Software <-> Politics


Here’s an analogy that came up this morning.

Liberals (Democrats) are like new CS grads.  They are excited about writing new code (laws) and disdainful of the negative predictions others make based on their hard-earned experience (believe in the perfectibility of people/software).

Conservatives are like grim old maintenance programmers.  They have seen fads and standards come and go, and know that attempting to fix one thing might break something else and make the whole system worse.  Unfortunately this sometimes leads them to defend the indefensible (States’ rights objections to the Civil Rights Act).  They’re often infatuated with process at the expense of outcome (strict constructionism).

Both views offer valuable insights and visible pitfalls.  But where is the party of refactoring?

Less Fatal: Peptic Ulcer


People don’t die of peptic ulcers so often anymore.  Here’s a nice picture:

Relevant dates include 1982, which is when Marshall and Warren identified H. pylori.  It gets a bit steeper after 1994, when the CDC starts promoting antibiotic treatment of peptic ulcer disease.  By 2005, when Warren and Marshall receive the Nobel Prize, it’s down around 1 per 100,000.

I was unable to find Canadian data before 2000.  US data is stitched together from three different coding systems: 1968-1978 ICD-8; 1979-1998 ICD-9; 1999-2010 ICD-10.

Take away: Better supportive care cuts deaths by 40% from 1968 – 1980.  Better treatment cuts another 40% (or, 2/3 of remaining deaths).

The Future was Last Week


In the future, we will have roving autonomous self-assembling bioreactors which will take in cellulosic matter, and convert it to natural gas and bio-available nutrients including complex amino acid chains. Some units will allow on-line collection of liquid food product, which can either be transported as-is or condensed into various solid, more easily stored forms, while other units will have to be deactivated and disassembled in order to yield edible matter.

In this way, we will be able to harvest the solar energy dumped on vast portions of the North American continent, currently growing useless native grasses, and instead have useful industrial feedstocks such as methane, butyric acid and long-chain hydrocarbon carboxylates.

They might even look a little like this:



Also we’ll have minature flying drone robots that collect plant matter, process it into sugar, and store it in custom-sized 3D-printed wrappers.


My point: buzzwords make everything sound good.

Not actually one of the reasons why we homeschool


But hey, if school kids are a) seeing knife wielding bullies and b) getting told to “not get involved” and quasi-punished for intervening, then well, maybe there’s more reasons to homeschool than I think.

Of course, this is Calgary.

Links via Gawker

Prague Floods Again


Looks like some dimwit opened Flood Control Dam #3 again… Now we’ll see if flood management has improved since the 2002 floods. My prediction: no. Half the metro is already flooded, apparently.

Here’s the BBC article

Chai vs. Tea


Czech has ‘čaj’, Japanese has ‘お茶’ (o-cha where the ‘o’ is honorific, so ignore it).  But English has ‘tea’, French has ‘thé’, Finnish has ‘tee’.

WALS has a nice map of the differences between world languages.  The interesting cases are where there’s an isolated blue dot in a red field or vice-versa.  For example, Hebrew uses ‘te’ while surrounding languages have  ‘cha’; not too surprising considering the influence of European languages on modern Hebrew.  But Basque and Portuguese use ‘cha’ while all other Romance languages use ‘te’ – I understand that the Portuguese made independent contact with the Far East, but why the Basque?  And why does Lesser Antillean French Creole use ‘cha’ when French uses ‘te’?  Why do Polish and Lithuanian have their own words, not loan-words?  Must be some  interesting stories there…