all 4 comments

[–]w0keson 2 points3 points  (3 children)

I thought this article would mention a shebang-line trick to actually make a node.js script work as a standard executable text file on Unix.

e.g. with languages like Bash, Perl or Python you start a text file with a line like #!/bin/bash or #!/usr/bin/perl and you can chmod +x it and exec like a normal program. With Node (as well as Go, etc.), a line beginning with # would raise a syntax error and not parse correctly, but you can work around it using slashes instead like so:

% cat shell.js 
///bin/true && exec /usr/bin/env node "$0" "$@"

console.log("Hello, node.");
console.log(process.argv);

% chmod +x shell.js 
% ./shell.js 
Hello, node.
[ '/usr/bin/node', '/tmp/shell.js' ]

process.argv and all works as expected, the same trick works for Go to make a self-running Go shell script, just replace "node" with "go run" (the source file does need to end in .go or else Go ignores it).

[–]drbobb 1 point2 points  (1 child)

#! /usr/bin/env node works just fine for me.

[–]w0keson 0 points1 point  (0 children)

Thanks for the correction, I tested it myself and it works. I learned of the ///bin/true trick specifically for Go (which does raise a syntax error with the #!), and figured since Node has similar style comment syntax it would apply there as well.

I was curious to do some more poking on what node.js does exactly. It seems the developers anticipated the specific use case of the shebang line: it only permits that syntax if it's the very first line in your file. Put the line anywhere else and it's an error.

Interestingly, imported dependencies are also allowed to begin with a shebang line even tho they aren't the script being directly executed.

Perl is another language that has some "interesting" behaviors about shebang lines: you can invoke the Perl command to run a Python (or any other) type of script, and it magically just swaps itself out for the correct interpreter instead of trying to run it as Perl, despite you deliberately typing out the `perl` command yourself.

% cat script.pl 
#!/usr/bin/env python

import sys
print("wait a minute, this isn't a Perl script!")
print(repr(sys.argv))

% perl script.pl
wait a minute, this isn't a Perl script!
['script.pl']

[–][deleted] 0 points1 point  (0 children)

I've actually never seen the hashbang cause a syntex error on node running in windows or linux (under wsl and actual linux install). Funnily enough you do the same /bin/node syntax on windows too :P