146

I'm trying to create a script for node.js that will work in multiple environments. Particularly for me, I'm switching back and forth between OS X and Ubuntu. In the former, Node is installed as node, but in the latter it is nodejs. At the top of my script, I can have:

#!/usr/bin/env node 

or

#!/usr/bin/env nodejs 

I'd rather have the script run as an executable for either environment as long as node is installed rather than have one or the other have to specify the command (./script-name.js vs. node script-name.js).

Is there any way to specify a backup hashbang or one that is compatible in either case for node.js?

4
  • you could make a wrapper shell script to call your script, that tries to find out where node lives and what it is called. Commented Dec 17, 2013 at 15:48
  • 4
    Lots of suggestions in this answer on the Unix site - unix.stackexchange.com/questions/65235/… Commented Dec 17, 2013 at 15:58
  • I have a nodejs script that I changed from #!/usr/bin/node to #!/usr/bin/nodejs when I upgraded from Ubuntu 12.04 to 12.10. And it's invoked from a wrapper that checks for both. For discussion of the #!/usr/bin/env hack, see this question and my answer. Commented Dec 8, 2014 at 19:08
  • 1
    There is TC39 proposal in Stage 3 called "Hashbang Grammar" which aims to standarize used hashbangs: github.com/tc39/proposal-hashbang Commented Sep 19, 2019 at 10:58

1 Answer 1

248

If your script is intended for use by Node developers, you should absolutely just use

#!/usr/bin/env node 

and not bother trying for compatibility with people who only have Node installed as nodejs.

Rationale:

  • It's what the cool kids are doing, and if you don't do it too, you're not cool. Major node projects like jshint, karma, bower, and even npm simply use #!/usr/bin/env node as the shebang for their executable scripts.
  • Because the cool kids are doing it, anyone who works with Node on Ubuntu has set up a /usr/bin/node as a symlink to nodejs. There are highly-viewed instructions on doing this here on Stack Overflow, and all over the web. There was even the nodejs-legacy package whose entire purpose was to create this symlink for you. People who use Node know how to fix this problem on Ubuntu, and they have to if they want to use pretty much any software ever written in Node.
  • The problem doesn't even seem to exist any more on Ubuntu 14.04; I just purged Node and ran an apt-get install nodejs and it created /usr/bin/node as a symlink to /etc/alternatives/node. People afflicted by this issue are, I suspect, a shrinking minority.

Even if you're targeting Node-illiterate people, you may still want to use #!/usr/bin/env node, perhaps adding the possible need for manual symlink creation or installation of the nodejs-legacy package to your installation documentation if you deem it necessary. Note that if somebody with nodejs but not node available tries to run your program with the above shebang, they'll see:

/usr/bin/env: node: No such file or directory

and Googling that will give them the fix in the first result and many times on the first page.

If you truly, desperately want to make sure that the user can run your software on a system where nodejs is available but node is not (or where node is actually the Amateur Packet Radio Node program), then you can use this "two-line shebang" taken from Unix & Linux Stack Exchange:

#!/bin/sh ':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@" console.log('Hello world!'); 

but do you really need to do this when almost nobody else in the Node world is?

Sign up to request clarification or add additional context in comments.

2 Comments

If support for the nodejs executable is preferred, you might find it slightly prettier to use a shebang with #!/bin/sh and //bin/false || exec "$(command -v nodejs || command -v node)" "$0".
Note that you can't pass arguments to node on Linux, such as --experimental-modules, if you use this env shebang line. There are hacks around, but they're ugly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.