javashellnashornjjs

Writing a `jjs` shebanged script that accepts just arguments


Supposedly jjs is the Java 8 version of nashorn, ready for shell-scripting. However when I write a file with execute permission as:

#!/usr/bin/jjs
arguments.forEach(function(v,i,a){print(v);});

Running it produces some not so ideal shell-scripting behavior:

$./file.js
$./file.js one two
java.io.IOException: one is not a file
$./file.js -- one two
one
two
$./file.js file.js -- one two # what were they thinking
one
two
one
two
$

So, I don't ever want this script I'm writing to allow for the arbitrary interpretation of a file after it runs, maybe I should use -- in the shebang like:

#!/usr/bin/jjs --
arguments.forEach(function(v,i,a){print(v);});

But this gets less useful:

$./file.js
jjs>^D
$./file.js one two
jjs>^D
$./file.js -- one two
jjs>

Yes, being dropped into a REPL prompt is exactly what I thought should not happen.

How am I supposed to make it possible to execute a script with arguments that are passed directly and not interpreted by jjs itself such that I can get behavior like:

$./file.js one two
one
two
$

Solution

  • The example works as expected in the JDK 9 version of Nashorn. I'll take care of backporting the required patches so they can appear in one of the upcoming 8u releases.

    Update: the required changes are backported to the 8u stream, but it is not clear at what point there will be a release. The early access releases of JDK 9 available from https://jdk9.java.net/download/ have the shebang feature, and also other extensions, such as piping support for the $EXEC builtin.